[Lldb-commits] [lldb] 4f991cc - [lldb-dap] Make connection URLs match lldb (#144770)

2025-06-19 Thread via lldb-commits

Author: Jonas Devlieghere
Date: 2025-06-19T20:48:07-05:00
New Revision: 4f991cc99523e4bb7a0d96cee9f5c3a64bf2bc8e

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

LOG: [lldb-dap] Make connection URLs match lldb (#144770)

Use the same scheme as ConnectionFileDescriptor::Connect and use
"listen" and "accept". Addresses feedback from a Pavel in a different PR
[1].

[1] https://github.com/llvm/llvm-project/pull/143628#discussion_r2152225200

Added: 


Modified: 
lldb/include/lldb/Host/Socket.h
lldb/source/Host/common/Socket.cpp
lldb/test/API/tools/lldb-dap/server/TestDAP_server.py
lldb/tools/lldb-dap/Options.td
lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts
lldb/tools/lldb-dap/tool/lldb-dap.cpp

Removed: 




diff  --git a/lldb/include/lldb/Host/Socket.h b/lldb/include/lldb/Host/Socket.h
index 4585eac12efb9..c313aa4f6d26b 100644
--- a/lldb/include/lldb/Host/Socket.h
+++ b/lldb/include/lldb/Host/Socket.h
@@ -74,6 +74,11 @@ class Socket : public IOObject {
 ProtocolUnixAbstract
   };
 
+  enum SocketMode {
+ModeAccept,
+ModeConnect,
+  };
+
   struct HostAndPort {
 std::string hostname;
 uint16_t port;
@@ -83,6 +88,10 @@ class Socket : public IOObject {
 }
   };
 
+  using ProtocolModePair = std::pair;
+  static std::optional
+  GetProtocolAndMode(llvm::StringRef scheme);
+
   static const NativeSocket kInvalidSocketValue;
 
   ~Socket() override;

diff  --git a/lldb/source/Host/common/Socket.cpp 
b/lldb/source/Host/common/Socket.cpp
index 76f74401ac4d0..5c5cd653c3d9e 100644
--- a/lldb/source/Host/common/Socket.cpp
+++ b/lldb/source/Host/common/Socket.cpp
@@ -271,7 +271,8 @@ Socket::UdpConnect(llvm::StringRef host_and_port) {
   return UDPSocket::CreateConnected(host_and_port);
 }
 
-llvm::Expected Socket::DecodeHostAndPort(llvm::StringRef 
host_and_port) {
+llvm::Expected
+Socket::DecodeHostAndPort(llvm::StringRef host_and_port) {
   static llvm::Regex g_regex("([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+)");
   HostAndPort ret;
   llvm::SmallVector matches;
@@ -347,8 +348,8 @@ Status Socket::Write(const void *buf, size_t &num_bytes) {
   ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64
   " (error = %s)",
   static_cast(this), static_cast(m_socket), buf,
-  static_cast(src_len),
-  static_cast(bytes_sent), error.AsCString());
+  static_cast(src_len), static_cast(bytes_sent),
+  error.AsCString());
   }
 
   return error;
@@ -476,3 +477,28 @@ llvm::raw_ostream 
&lldb_private::operator<<(llvm::raw_ostream &OS,
 const Socket::HostAndPort &HP) {
   return OS << '[' << HP.hostname << ']' << ':' << HP.port;
 }
+
+std::optional
+Socket::GetProtocolAndMode(llvm::StringRef scheme) {
+  // Keep in sync with ConnectionFileDescriptor::Connect.
+  return llvm::StringSwitch>(scheme)
+  .Case("listen", ProtocolModePair{SocketProtocol::ProtocolTcp,
+   SocketMode::ModeAccept})
+  .Cases("accept", "unix-accept",
+ ProtocolModePair{SocketProtocol::ProtocolUnixDomain,
+  SocketMode::ModeAccept})
+  .Case("unix-abstract-accept",
+ProtocolModePair{SocketProtocol::ProtocolUnixAbstract,
+ SocketMode::ModeAccept})
+  .Cases("connect", "tcp-connect",
+ ProtocolModePair{SocketProtocol::ProtocolTcp,
+  SocketMode::ModeConnect})
+  .Case("udp", ProtocolModePair{SocketProtocol::ProtocolTcp,
+SocketMode::ModeConnect})
+  .Case("unix-connect", 
ProtocolModePair{SocketProtocol::ProtocolUnixDomain,
+ SocketMode::ModeConnect})
+  .Case("unix-abstract-connect",
+ProtocolModePair{SocketProtocol::ProtocolUnixAbstract,
+ SocketMode::ModeConnect})
+  .Default(std::nullopt);
+}

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..592a4cfb0a88b 100644
--- a/lldb/test/API/tools/lldb-dap/server/TestDAP_server.py
+++ b/lldb/test/API/tools/lldb-dap/server/TestDAP_server.py
@@ -54,7 +54,7 @@ def test_server_port(self):
 Test launching a binary with a lldb-dap in server mode on a specific 
port.
 """
 self.build()
-(_, connection) = self.start_server(connection="tcp://localhost:0")
+(_, connection) = self.start_server(connection="listen://localhost:0")
 self.run_debug_session(connection, "Alice")
 self.run_debug_session(connection, "Bob")
 
@@ -72,7 +72,7 @@ def cleanup():
 self.addTearDownHook(cle

[Lldb-commits] [lldb] [lldb-dap] Make connection URLs match lldb (PR #144770)

2025-06-19 Thread Jonas Devlieghere via lldb-commits

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


[Lldb-commits] [lldb] [lldb] Add Model Context Protocol (MCP) support to LLDB (PR #143628)

2025-06-19 Thread Jonas Devlieghere via lldb-commits

https://github.com/JDevlieghere updated 
https://github.com/llvm/llvm-project/pull/143628

>From d0421ef2751a827a09d1ea5e9eb4457afea7c59d Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere 
Date: Thu, 12 Jun 2025 16:33:55 -0700
Subject: [PATCH] [lldb] Add MCP support to LLDB

https://discourse.llvm.org/t/rfc-adding-mcp-support-to-lldb/86798
---
 lldb/cmake/modules/LLDBConfig.cmake   |   1 +
 lldb/include/lldb/Core/Debugger.h |   6 +
 lldb/include/lldb/Core/PluginManager.h|  11 +
 lldb/include/lldb/Core/ProtocolServer.h   |  39 +++
 .../Interpreter/CommandOptionArgumentTable.h  |   1 +
 lldb/include/lldb/lldb-enumerations.h |   1 +
 lldb/include/lldb/lldb-forward.h  |   3 +-
 lldb/include/lldb/lldb-private-interfaces.h   |   2 +
 lldb/source/Commands/CMakeLists.txt   |   1 +
 .../Commands/CommandObjectProtocolServer.cpp  | 176 ++
 .../Commands/CommandObjectProtocolServer.h|  25 ++
 lldb/source/Core/CMakeLists.txt   |   1 +
 lldb/source/Core/Debugger.cpp |  24 ++
 lldb/source/Core/PluginManager.cpp|  32 ++
 lldb/source/Core/ProtocolServer.cpp   |  21 ++
 .../source/Interpreter/CommandInterpreter.cpp |   2 +
 lldb/source/Plugins/CMakeLists.txt|   4 +
 lldb/source/Plugins/Protocol/CMakeLists.txt   |   1 +
 .../Plugins/Protocol/MCP/CMakeLists.txt   |  13 +
 lldb/source/Plugins/Protocol/MCP/MCPError.cpp |  34 ++
 lldb/source/Plugins/Protocol/MCP/MCPError.h   |  33 ++
 lldb/source/Plugins/Protocol/MCP/Protocol.cpp | 214 
 lldb/source/Plugins/Protocol/MCP/Protocol.h   | 128 +++
 .../Protocol/MCP/ProtocolServerMCP.cpp| 327 ++
 .../Plugins/Protocol/MCP/ProtocolServerMCP.h  | 100 ++
 lldb/source/Plugins/Protocol/MCP/Tool.cpp |  81 +
 lldb/source/Plugins/Protocol/MCP/Tool.h   |  56 +++
 lldb/unittests/CMakeLists.txt |   4 +
 lldb/unittests/DAP/ProtocolTypesTest.cpp  |  38 +-
 lldb/unittests/Protocol/CMakeLists.txt|  12 +
 .../Protocol/ProtocolMCPServerTest.cpp| 291 
 lldb/unittests/Protocol/ProtocolMCPTest.cpp   | 135 
 lldb/unittests/TestingSupport/TestUtilities.h |   9 +
 33 files changed, 1803 insertions(+), 23 deletions(-)
 create mode 100644 lldb/include/lldb/Core/ProtocolServer.h
 create mode 100644 lldb/source/Commands/CommandObjectProtocolServer.cpp
 create mode 100644 lldb/source/Commands/CommandObjectProtocolServer.h
 create mode 100644 lldb/source/Core/ProtocolServer.cpp
 create mode 100644 lldb/source/Plugins/Protocol/CMakeLists.txt
 create mode 100644 lldb/source/Plugins/Protocol/MCP/CMakeLists.txt
 create mode 100644 lldb/source/Plugins/Protocol/MCP/MCPError.cpp
 create mode 100644 lldb/source/Plugins/Protocol/MCP/MCPError.h
 create mode 100644 lldb/source/Plugins/Protocol/MCP/Protocol.cpp
 create mode 100644 lldb/source/Plugins/Protocol/MCP/Protocol.h
 create mode 100644 lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.cpp
 create mode 100644 lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.h
 create mode 100644 lldb/source/Plugins/Protocol/MCP/Tool.cpp
 create mode 100644 lldb/source/Plugins/Protocol/MCP/Tool.h
 create mode 100644 lldb/unittests/Protocol/CMakeLists.txt
 create mode 100644 lldb/unittests/Protocol/ProtocolMCPServerTest.cpp
 create mode 100644 lldb/unittests/Protocol/ProtocolMCPTest.cpp

diff --git a/lldb/cmake/modules/LLDBConfig.cmake 
b/lldb/cmake/modules/LLDBConfig.cmake
index 37b823feb584b..8c30b6e09d2c7 100644
--- a/lldb/cmake/modules/LLDBConfig.cmake
+++ b/lldb/cmake/modules/LLDBConfig.cmake
@@ -67,6 +67,7 @@ add_optional_dependency(LLDB_ENABLE_FBSDVMCORE "Enable 
libfbsdvmcore support in
 
 option(LLDB_USE_ENTITLEMENTS "When codesigning, use entitlements if available" 
ON)
 option(LLDB_BUILD_FRAMEWORK "Build LLDB.framework (Darwin only)" OFF)
+option(LLDB_ENABLE_PROTOCOL_SERVERS "Enable protocol servers (e.g. MCP) in 
LLDB" ON)
 option(LLDB_NO_INSTALL_DEFAULT_RPATH "Disable default RPATH settings in 
binaries" OFF)
 option(LLDB_USE_SYSTEM_DEBUGSERVER "Use the system's debugserver for testing 
(Darwin only)." OFF)
 option(LLDB_SKIP_STRIP "Whether to skip stripping of binaries when installing 
lldb." OFF)
diff --git a/lldb/include/lldb/Core/Debugger.h 
b/lldb/include/lldb/Core/Debugger.h
index 2087ef2a11562..9f82466a83417 100644
--- a/lldb/include/lldb/Core/Debugger.h
+++ b/lldb/include/lldb/Core/Debugger.h
@@ -602,6 +602,10 @@ class Debugger : public 
std::enable_shared_from_this,
   void FlushProcessOutput(Process &process, bool flush_stdout,
   bool flush_stderr);
 
+  void AddProtocolServer(lldb::ProtocolServerSP protocol_server_sp);
+  void RemoveProtocolServer(lldb::ProtocolServerSP protocol_server_sp);
+  lldb::ProtocolServerSP GetProtocolServer(llvm::StringRef protocol) const;
+
   SourceManager::SourceFileCache &GetSourceFileCache() {
 return m_source_file_cache;
   }
@@ -772,6 +776,8 @@ class Deb

[Lldb-commits] [lldb] [lldb] Add DWARFExpressionEntry and GetExpressionEntryAtAddress() to … (PR #144238)

2025-06-19 Thread Abdullah Mohammad Amin via lldb-commits


@@ -53,6 +53,27 @@ bool DWARFExpressionList::ContainsAddress(lldb::addr_t 
func_load_addr,
   return GetExpressionAtAddress(func_load_addr, addr) != nullptr;
 }
 
+llvm::Expected
+DWARFExpressionList::GetExpressionEntryAtAddress(lldb::addr_t func_load_addr,
+ lldb::addr_t load_addr) const 
{
+  if (const DWARFExpression *expr = GetAlwaysValidExpr()) {
+return DWARFExpressionEntry{0, LLDB_INVALID_ADDRESS, expr};
+  }
+
+  if (func_load_addr == LLDB_INVALID_ADDRESS)
+func_load_addr = m_func_file_addr;
+
+  addr_t addr = load_addr - func_load_addr + m_func_file_addr;
+  uint32_t index = m_exprs.FindEntryIndexThatContains(addr);
+  if (index == UINT32_MAX) {
+return llvm::createStringError(llvm::inconvertibleErrorCode(),
+   "No DWARF expression found for address 
0x%llx", addr);
+  }
+
+  const Entry &entry = *m_exprs.GetEntryAtIndex(index);
+  return DWARFExpressionEntry{entry.base, entry.GetRangeEnd(), &entry.data};
+}
+
 const DWARFExpression *
 DWARFExpressionList::GetExpressionAtAddress(lldb::addr_t func_load_addr,

UltimateForce21 wrote:

As you know the new function GetExpressionEntryAtAddress, does almost exact 
same thing as this one. I don't see this function being used anywhere else in 
the lldb code base, so maybe it can be removed, but to be safe I did not want 
to alter it. But from what I can tell, it should be okay to remove it. We can 
also choose to keep it and maybe refactor it to just call the 
GetExpressionEntryAtAddress and just return the `DWARFExpression *expr`.

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


[Lldb-commits] [lldb] [lldb-dap][test] Refactor runInTerminal Tests. (PR #144954)

2025-06-19 Thread Ebuka Ezike via lldb-commits

https://github.com/da-viper created 
https://github.com/llvm/llvm-project/pull/144954

Replace `isTestSupported` function with `skipIfBuildType` annotation.

Test that uses the `IsTestSupported` function are no longer run, as the size of 
lldb-dap binary is now more than `1mb`. 

Update the broken test. 

Fixes #108621  

We could probably check if the test now passes on `linux arm` since it was 
disabled because it timed out. I experienced the timeout after replacing the 
`IsTestSupported` with `skipIfBuildType`.

>From 8053b71588a0612f3650c7c4f07820f22215528f Mon Sep 17 00:00:00 2001
From: Ebuka Ezike 
Date: Thu, 19 Jun 2025 21:33:38 +0100
Subject: [PATCH] [lldb-dap][test] cleanup runInTerminal Test.

Replace `isTestSupported` function with `skipIfBuildType` annotation.
---
 .../test/tools/lldb-dap/dap_server.py | 12 ++-
 .../restart/TestDAP_restart_runInTerminal.py  | 87 ++-
 .../runInTerminal/TestDAP_runInTerminal.py| 71 +--
 .../API/tools/lldb-dap/runInTerminal/main.c   |  7 +-
 4 files changed, 78 insertions(+), 99 deletions(-)

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index 6d32491eaa5e9..0fe36cd4bc71f 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -179,9 +179,13 @@ def encode_content(cls, s: str) -> bytes:
 @classmethod
 def validate_response(cls, command, response):
 if command["command"] != response["command"]:
-raise ValueError("command mismatch in response")
+raise ValueError(
+f"command mismatch in response {command['command']} != 
{response['command']}"
+)
 if command["seq"] != response["request_seq"]:
-raise ValueError("seq mismatch in response")
+raise ValueError(
+f"seq mismatch in response {command['seq']} != 
{response['request_seq']}"
+)
 
 def _read_packet_thread(self):
 done = False
@@ -404,8 +408,8 @@ def send_recv(self, command):
 self.reverse_requests.append(response_or_request)
 if response_or_request["command"] == "runInTerminal":
 subprocess.Popen(
-response_or_request["arguments"]["args"],
-env=response_or_request["arguments"]["env"],
+response_or_request["arguments"].get("args"),
+env=response_or_request["arguments"].get("env", {}),
 )
 self.send_packet(
 {
diff --git 
a/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py 
b/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py
index e23d34bd99308..3ba7deb285de9 100644
--- a/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py
+++ b/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py
@@ -2,23 +2,35 @@
 Test lldb-dap RestartRequest.
 """
 
-import os
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import line_number
+from typing import Dict, Any, List
+
 import lldbdap_testcase
+from lldbsuite.test.decorators import skipIfWindows, skipIf, skipIfBuildType
+from lldbsuite.test.lldbtest import line_number
 
 
+@skipIfBuildType(["debug"])
 class TestDAP_restart_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
-def isTestSupported(self):
-try:
-# We skip this test for debug builds because it takes too long
-# parsing lldb's own debug info. Release builds are fine.
-# Checking the size of the lldb-dap binary seems to be a decent
-# proxy for a quick detection. It should be far less than 1 MB in
-# Release builds.
-return os.path.getsize(os.environ["LLDBDAP_EXEC"]) < 100
-except:
-return False
+def verify_stopped_on_entry(self, stopped_events: List[Dict[str, Any]]):
+seen_stopped_event = 0
+for stopped_event in stopped_events:
+body = stopped_event.get("body")
+if body is None:
+continue
+
+reason = body.get("reason")
+if reason is None:
+continue
+
+self.assertNotEqual(
+reason,
+"breakpoint",
+'verify stop after restart isn\'t "main" breakpoint',
+)
+if reason == "entry":
+seen_stopped_event += 1
+
+self.assertEqual(seen_stopped_event, 1, "expect only one stopped entry 
event.")
 
 @skipIfWindows
 @skipIf(oslist=["linux"], archs=["arm$"])  # Always times out on buildbot
@@ -27,8 +39,6 @@ def test_basic_functionality(self):
 Test basic restarting functionality when the process is running in
 a terminal.
 """
- 

[Lldb-commits] [lldb] [lldb-dap][test] Refactor runInTerminal Tests. (PR #144954)

2025-06-19 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Ebuka Ezike (da-viper)


Changes

Replace `isTestSupported` function with `skipIfBuildType` annotation.

Test that uses the `IsTestSupported` function are no longer run, as the size of 
lldb-dap binary is now more than `1mb`. 

Update the broken test. 

Fixes #108621  

We could probably check if the test now passes on `linux arm` since it was 
disabled because it timed out. I experienced the timeout after replacing the 
`IsTestSupported` with `skipIfBuildType`.

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


4 Files Affected:

- (modified) lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
(+8-4) 
- (modified) 
lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py (+46-41) 
- (modified) 
lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py (+21-50) 
- (modified) lldb/test/API/tools/lldb-dap/runInTerminal/main.c (+3-4) 


``diff
diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index 6d32491eaa5e9..0fe36cd4bc71f 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -179,9 +179,13 @@ def encode_content(cls, s: str) -> bytes:
 @classmethod
 def validate_response(cls, command, response):
 if command["command"] != response["command"]:
-raise ValueError("command mismatch in response")
+raise ValueError(
+f"command mismatch in response {command['command']} != 
{response['command']}"
+)
 if command["seq"] != response["request_seq"]:
-raise ValueError("seq mismatch in response")
+raise ValueError(
+f"seq mismatch in response {command['seq']} != 
{response['request_seq']}"
+)
 
 def _read_packet_thread(self):
 done = False
@@ -404,8 +408,8 @@ def send_recv(self, command):
 self.reverse_requests.append(response_or_request)
 if response_or_request["command"] == "runInTerminal":
 subprocess.Popen(
-response_or_request["arguments"]["args"],
-env=response_or_request["arguments"]["env"],
+response_or_request["arguments"].get("args"),
+env=response_or_request["arguments"].get("env", {}),
 )
 self.send_packet(
 {
diff --git 
a/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py 
b/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py
index e23d34bd99308..3ba7deb285de9 100644
--- a/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py
+++ b/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py
@@ -2,23 +2,35 @@
 Test lldb-dap RestartRequest.
 """
 
-import os
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import line_number
+from typing import Dict, Any, List
+
 import lldbdap_testcase
+from lldbsuite.test.decorators import skipIfWindows, skipIf, skipIfBuildType
+from lldbsuite.test.lldbtest import line_number
 
 
+@skipIfBuildType(["debug"])
 class TestDAP_restart_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
-def isTestSupported(self):
-try:
-# We skip this test for debug builds because it takes too long
-# parsing lldb's own debug info. Release builds are fine.
-# Checking the size of the lldb-dap binary seems to be a decent
-# proxy for a quick detection. It should be far less than 1 MB in
-# Release builds.
-return os.path.getsize(os.environ["LLDBDAP_EXEC"]) < 100
-except:
-return False
+def verify_stopped_on_entry(self, stopped_events: List[Dict[str, Any]]):
+seen_stopped_event = 0
+for stopped_event in stopped_events:
+body = stopped_event.get("body")
+if body is None:
+continue
+
+reason = body.get("reason")
+if reason is None:
+continue
+
+self.assertNotEqual(
+reason,
+"breakpoint",
+'verify stop after restart isn\'t "main" breakpoint',
+)
+if reason == "entry":
+seen_stopped_event += 1
+
+self.assertEqual(seen_stopped_event, 1, "expect only one stopped entry 
event.")
 
 @skipIfWindows
 @skipIf(oslist=["linux"], archs=["arm$"])  # Always times out on buildbot
@@ -27,8 +39,6 @@ def test_basic_functionality(self):
 Test basic restarting functionality when the process is running in
 a terminal.
 """
-if not self.isTestSupported():
-return
 line_A = line_number("main.c", "// breakpoint A")
 

[Lldb-commits] [lldb] [lldb-dap][test] Refactor runInTerminal Tests. (PR #144954)

2025-06-19 Thread Ebuka Ezike via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap][test] Refactor runInTerminal Tests. (PR #144954)

2025-06-19 Thread Ebuka Ezike via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap] Splitting ProtocolTypesTest into parts. (PR #144595)

2025-06-19 Thread Ebuka Ezike via lldb-commits


@@ -30,6 +30,20 @@
   }
 
 namespace lldb_private {
+
+/// Returns a pretty printed json string of a `llvm::json::Value`.
+std::string pp(const llvm::json::Value &E);

da-viper wrote:

Since we are moving it, we could use a more descriptive name like `pprint`, 
`json_print` or `to_string` 

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


[Lldb-commits] [lldb] [lldb-dap] Splitting ProtocolTypesTest into parts. (PR #144595)

2025-06-19 Thread Ebuka Ezike via lldb-commits

https://github.com/da-viper approved this pull request.


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


[Lldb-commits] [lldb] [LLDB] Update DIL to handle smart pointers; add more tests. (PR #143786)

2025-06-19 Thread via lldb-commits

https://github.com/cmtice updated 
https://github.com/llvm/llvm-project/pull/143786

>From 837e8dd36446104b207248c9dbf372a6da6ffbf1 Mon Sep 17 00:00:00 2001
From: Caroline Tice 
Date: Wed, 11 Jun 2025 14:24:17 -0700
Subject: [PATCH 1/4] [LLDB] Update DIL to handle smart pointers; add more
 tests.

This updates the DIL implementation to handle smart pointers (accessing
field members and dereferencing) in the same way the current 'frame
variable' implementation does.  It also adds tests for handling smart pointers,
as well as some additional DIL tests.
---
 lldb/source/ValueObject/DILEval.cpp   |  9 +++-
 .../frame/var-dil/basics/BitField/Makefile|  3 ++
 .../BitField/TestFrameVarDILBitField.py   | 38 
 .../frame/var-dil/basics/BitField/main.cpp| 44 +++
 .../frame/var-dil/basics/Indirection/Makefile |  3 ++
 .../Indirection/TestFrameVarDILIndirection.py | 36 +++
 .../frame/var-dil/basics/Indirection/main.cpp | 14 ++
 .../basics/PointerDereference/Makefile|  3 ++
 .../TestFrameVarDILPointerDereference.py  | 30 +
 .../basics/PointerDereference/main.cpp| 32 ++
 .../frame/var-dil/basics/QualifiedId/Makefile |  3 ++
 .../QualifiedId/TestFrameVarDILQualifiedId.py | 29 
 .../frame/var-dil/basics/QualifiedId/main.cpp | 18 
 .../frame/var-dil/basics/SharedPtr/Makefile   |  6 +++
 .../SharedPtr/TestFrameVarDILSharedPtr.py | 36 +++
 .../TestFrameVarDILSharedPtrDeref.py  | 29 
 .../frame/var-dil/basics/SharedPtr/main.cpp   | 26 +++
 .../frame/var-dil/basics/UniquePtr/Makefile   |  6 +++
 .../UniquePtr/TestFrameVarDILUniquePtr.py | 28 
 .../TestFrameVarDILUniquePtrDeref.py  | 29 
 .../frame/var-dil/basics/UniquePtr/main.cpp   | 25 +++
 21 files changed, 446 insertions(+), 1 deletion(-)
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/BitField/Makefile
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/BitField/TestFrameVarDILBitField.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/BitField/main.cpp
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/Indirection/Makefile
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/Indirection/TestFrameVarDILIndirection.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/Indirection/main.cpp
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/PointerDereference/Makefile
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/PointerDereference/TestFrameVarDILPointerDereference.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/PointerDereference/main.cpp
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/QualifiedId/Makefile
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/QualifiedId/TestFrameVarDILQualifiedId.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/QualifiedId/main.cpp
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/SharedPtr/Makefile
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/SharedPtr/TestFrameVarDILSharedPtr.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/SharedPtr/TestFrameVarDILSharedPtrDeref.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/SharedPtr/main.cpp
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/UniquePtr/Makefile
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/UniquePtr/TestFrameVarDILUniquePtr.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/UniquePtr/TestFrameVarDILUniquePtrDeref.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/UniquePtr/main.cpp

diff --git a/lldb/source/ValueObject/DILEval.cpp 
b/lldb/source/ValueObject/DILEval.cpp
index c8cb54aa18a93..adc34e25766b3 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -253,6 +253,12 @@ Interpreter::Visit(const UnaryOpNode *node) {
   rhs = dynamic_rhs;
 
 lldb::ValueObjectSP child_sp = rhs->Dereference(error);
+if (!child_sp && m_use_synthetic) {
+  if (lldb::ValueObjectSP synth_obj_sp = rhs->GetSyntheticValue()) {
+error.Clear();
+child_sp = synth_obj_sp->Dereference(error);
+  }
+}
 if (error.Fail())
   return llvm::make_error(m_expr, error.AsCString(),
   node->GetLocation());
@@ -280,6 +286,7 @@ Interpreter::Visit(const MemberOfNode *node) {
   auto base_or_err = Evaluate(node->GetBase());
   if (!base_or_err)
 return base_or_err;
+  bool expr_is_ptr = node->GetIsArrow();
   lldb::ValueObjectSP base = *base_or_err;
 
   // Perform some basic type & correctness checking.
@@ -319,11 +326,11 @@ Interpreter::Visit(const MemberOfNode *node) {
 return llvm::make_error(
 m_expr, errMsg, node->GetLocation(

[Lldb-commits] [lldb] [LLDB] Update DIL to handle smart pointers; add more tests. (PR #143786)

2025-06-19 Thread via lldb-commits

cmtice wrote:

I *think* I have addressed all the review comments; please take another look.

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


[Lldb-commits] [lldb] [LLDB] Update DIL to handle smart pointers; add more tests. (PR #143786)

2025-06-19 Thread via lldb-commits

https://github.com/cmtice updated 
https://github.com/llvm/llvm-project/pull/143786

>From 837e8dd36446104b207248c9dbf372a6da6ffbf1 Mon Sep 17 00:00:00 2001
From: Caroline Tice 
Date: Wed, 11 Jun 2025 14:24:17 -0700
Subject: [PATCH 1/5] [LLDB] Update DIL to handle smart pointers; add more
 tests.

This updates the DIL implementation to handle smart pointers (accessing
field members and dereferencing) in the same way the current 'frame
variable' implementation does.  It also adds tests for handling smart pointers,
as well as some additional DIL tests.
---
 lldb/source/ValueObject/DILEval.cpp   |  9 +++-
 .../frame/var-dil/basics/BitField/Makefile|  3 ++
 .../BitField/TestFrameVarDILBitField.py   | 38 
 .../frame/var-dil/basics/BitField/main.cpp| 44 +++
 .../frame/var-dil/basics/Indirection/Makefile |  3 ++
 .../Indirection/TestFrameVarDILIndirection.py | 36 +++
 .../frame/var-dil/basics/Indirection/main.cpp | 14 ++
 .../basics/PointerDereference/Makefile|  3 ++
 .../TestFrameVarDILPointerDereference.py  | 30 +
 .../basics/PointerDereference/main.cpp| 32 ++
 .../frame/var-dil/basics/QualifiedId/Makefile |  3 ++
 .../QualifiedId/TestFrameVarDILQualifiedId.py | 29 
 .../frame/var-dil/basics/QualifiedId/main.cpp | 18 
 .../frame/var-dil/basics/SharedPtr/Makefile   |  6 +++
 .../SharedPtr/TestFrameVarDILSharedPtr.py | 36 +++
 .../TestFrameVarDILSharedPtrDeref.py  | 29 
 .../frame/var-dil/basics/SharedPtr/main.cpp   | 26 +++
 .../frame/var-dil/basics/UniquePtr/Makefile   |  6 +++
 .../UniquePtr/TestFrameVarDILUniquePtr.py | 28 
 .../TestFrameVarDILUniquePtrDeref.py  | 29 
 .../frame/var-dil/basics/UniquePtr/main.cpp   | 25 +++
 21 files changed, 446 insertions(+), 1 deletion(-)
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/BitField/Makefile
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/BitField/TestFrameVarDILBitField.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/BitField/main.cpp
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/Indirection/Makefile
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/Indirection/TestFrameVarDILIndirection.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/Indirection/main.cpp
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/PointerDereference/Makefile
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/PointerDereference/TestFrameVarDILPointerDereference.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/PointerDereference/main.cpp
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/QualifiedId/Makefile
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/QualifiedId/TestFrameVarDILQualifiedId.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/QualifiedId/main.cpp
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/SharedPtr/Makefile
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/SharedPtr/TestFrameVarDILSharedPtr.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/SharedPtr/TestFrameVarDILSharedPtrDeref.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/SharedPtr/main.cpp
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/UniquePtr/Makefile
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/UniquePtr/TestFrameVarDILUniquePtr.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/UniquePtr/TestFrameVarDILUniquePtrDeref.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/UniquePtr/main.cpp

diff --git a/lldb/source/ValueObject/DILEval.cpp 
b/lldb/source/ValueObject/DILEval.cpp
index c8cb54aa18a93..adc34e25766b3 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -253,6 +253,12 @@ Interpreter::Visit(const UnaryOpNode *node) {
   rhs = dynamic_rhs;
 
 lldb::ValueObjectSP child_sp = rhs->Dereference(error);
+if (!child_sp && m_use_synthetic) {
+  if (lldb::ValueObjectSP synth_obj_sp = rhs->GetSyntheticValue()) {
+error.Clear();
+child_sp = synth_obj_sp->Dereference(error);
+  }
+}
 if (error.Fail())
   return llvm::make_error(m_expr, error.AsCString(),
   node->GetLocation());
@@ -280,6 +286,7 @@ Interpreter::Visit(const MemberOfNode *node) {
   auto base_or_err = Evaluate(node->GetBase());
   if (!base_or_err)
 return base_or_err;
+  bool expr_is_ptr = node->GetIsArrow();
   lldb::ValueObjectSP base = *base_or_err;
 
   // Perform some basic type & correctness checking.
@@ -319,11 +326,11 @@ Interpreter::Visit(const MemberOfNode *node) {
 return llvm::make_error(
 m_expr, errMsg, node->GetLocation(

[Lldb-commits] [lldb] [LLDB] Update DIL to handle smart pointers; add more tests. (PR #143786)

2025-06-19 Thread via lldb-commits

https://github.com/cmtice updated 
https://github.com/llvm/llvm-project/pull/143786

>From 837e8dd36446104b207248c9dbf372a6da6ffbf1 Mon Sep 17 00:00:00 2001
From: Caroline Tice 
Date: Wed, 11 Jun 2025 14:24:17 -0700
Subject: [PATCH 1/6] [LLDB] Update DIL to handle smart pointers; add more
 tests.

This updates the DIL implementation to handle smart pointers (accessing
field members and dereferencing) in the same way the current 'frame
variable' implementation does.  It also adds tests for handling smart pointers,
as well as some additional DIL tests.
---
 lldb/source/ValueObject/DILEval.cpp   |  9 +++-
 .../frame/var-dil/basics/BitField/Makefile|  3 ++
 .../BitField/TestFrameVarDILBitField.py   | 38 
 .../frame/var-dil/basics/BitField/main.cpp| 44 +++
 .../frame/var-dil/basics/Indirection/Makefile |  3 ++
 .../Indirection/TestFrameVarDILIndirection.py | 36 +++
 .../frame/var-dil/basics/Indirection/main.cpp | 14 ++
 .../basics/PointerDereference/Makefile|  3 ++
 .../TestFrameVarDILPointerDereference.py  | 30 +
 .../basics/PointerDereference/main.cpp| 32 ++
 .../frame/var-dil/basics/QualifiedId/Makefile |  3 ++
 .../QualifiedId/TestFrameVarDILQualifiedId.py | 29 
 .../frame/var-dil/basics/QualifiedId/main.cpp | 18 
 .../frame/var-dil/basics/SharedPtr/Makefile   |  6 +++
 .../SharedPtr/TestFrameVarDILSharedPtr.py | 36 +++
 .../TestFrameVarDILSharedPtrDeref.py  | 29 
 .../frame/var-dil/basics/SharedPtr/main.cpp   | 26 +++
 .../frame/var-dil/basics/UniquePtr/Makefile   |  6 +++
 .../UniquePtr/TestFrameVarDILUniquePtr.py | 28 
 .../TestFrameVarDILUniquePtrDeref.py  | 29 
 .../frame/var-dil/basics/UniquePtr/main.cpp   | 25 +++
 21 files changed, 446 insertions(+), 1 deletion(-)
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/BitField/Makefile
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/BitField/TestFrameVarDILBitField.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/BitField/main.cpp
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/Indirection/Makefile
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/Indirection/TestFrameVarDILIndirection.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/Indirection/main.cpp
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/PointerDereference/Makefile
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/PointerDereference/TestFrameVarDILPointerDereference.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/PointerDereference/main.cpp
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/QualifiedId/Makefile
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/QualifiedId/TestFrameVarDILQualifiedId.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/QualifiedId/main.cpp
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/SharedPtr/Makefile
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/SharedPtr/TestFrameVarDILSharedPtr.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/SharedPtr/TestFrameVarDILSharedPtrDeref.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/SharedPtr/main.cpp
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/UniquePtr/Makefile
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/UniquePtr/TestFrameVarDILUniquePtr.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/UniquePtr/TestFrameVarDILUniquePtrDeref.py
 create mode 100644 
lldb/test/API/commands/frame/var-dil/basics/UniquePtr/main.cpp

diff --git a/lldb/source/ValueObject/DILEval.cpp 
b/lldb/source/ValueObject/DILEval.cpp
index c8cb54aa18a93..adc34e25766b3 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -253,6 +253,12 @@ Interpreter::Visit(const UnaryOpNode *node) {
   rhs = dynamic_rhs;
 
 lldb::ValueObjectSP child_sp = rhs->Dereference(error);
+if (!child_sp && m_use_synthetic) {
+  if (lldb::ValueObjectSP synth_obj_sp = rhs->GetSyntheticValue()) {
+error.Clear();
+child_sp = synth_obj_sp->Dereference(error);
+  }
+}
 if (error.Fail())
   return llvm::make_error(m_expr, error.AsCString(),
   node->GetLocation());
@@ -280,6 +286,7 @@ Interpreter::Visit(const MemberOfNode *node) {
   auto base_or_err = Evaluate(node->GetBase());
   if (!base_or_err)
 return base_or_err;
+  bool expr_is_ptr = node->GetIsArrow();
   lldb::ValueObjectSP base = *base_or_err;
 
   // Perform some basic type & correctness checking.
@@ -319,11 +326,11 @@ Interpreter::Visit(const MemberOfNode *node) {
 return llvm::make_error(
 m_expr, errMsg, node->GetLocation(

[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

2025-06-19 Thread Charles Zablit via lldb-commits


@@ -236,199 +236,156 @@ static bool PrettyPrintFunctionNameWithArgs(Stream 
&out_stream,
   return true;
 }
 
-static std::optional
-GetDemangledBasename(const SymbolContext &sc) {
+static llvm::Expected>
+GetAndValidateInfo(const SymbolContext &sc) {
   Mangled mangled = sc.GetPossiblyInlinedFunctionName();
   if (!mangled)
-return std::nullopt;
+return llvm::createStringError("Function does not have a mangled name.");
 
   auto demangled_name = mangled.GetDemangledName().GetStringRef();
   if (demangled_name.empty())
-return std::nullopt;
+return llvm::createStringError(
+"Function '%s' does not have a demangled name.",
+mangled.GetMangledName().AsCString(""));
 
   const std::optional &info = mangled.GetDemangledInfo();
   if (!info)
-return std::nullopt;
+return llvm::createStringError(
+"Function '%s' does not have demangled info.", demangled_name.data());
 
   // Function without a basename is nonsense.
   if (!info->hasBasename())
-return std::nullopt;
+return llvm::createStringError(
+"DemangledInfo for '%s does not have basename range.",
+demangled_name.data());
 
-  return demangled_name.slice(info->BasenameRange.first,
-  info->BasenameRange.second);
+  return std::make_pair(demangled_name, *info);
 }
 
-static std::optional
-GetDemangledTemplateArguments(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+static llvm::Expected
+GetDemangledBasename(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  return demangled_name.slice(info.BasenameRange.first,
+  info.BasenameRange.second);
+}
 
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
+static llvm::Expected
+GetDemangledTemplateArguments(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
+
+  auto [demangled_name, info] = *info_or_err;
 
-  if (info->ArgumentsRange.first < info->BasenameRange.second)
-return std::nullopt;
+  if (info.ArgumentsRange.first < info.BasenameRange.second)
+return llvm::createStringError("Arguments range for '%s' is invalid.",
+   demangled_name.data());
 
-  return demangled_name.slice(info->BasenameRange.second,
-  info->ArgumentsRange.first);
+  return demangled_name.slice(info.BasenameRange.second,
+  info.ArgumentsRange.first);
 }
 
-static std::optional
+static llvm::Expected
 GetDemangledReturnTypeLHS(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  if (info.ScopeRange.first >= demangled_name.size())
+return llvm::createStringError(
+"Scope range for '%s' LHS return type is invalid.",
+demangled_name.data());
 
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
-
-  if (info->ScopeRange.first >= demangled_name.size())
-return std::nullopt;
-
-  return demangled_name.substr(0, info->ScopeRange.first);
+  return demangled_name.substr(0, info.ScopeRange.first);
 }
 
-static std::optional
+static llvm::Expected
 GetDemangledFunctionQualifiers(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
-
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
+  if (!info.hasQualifiers())
+return llvm::createStringError("Qualifiers range for '%s' is invalid.",
+   demangled_name.data());
 
-  if (info->QualifiersRange.second < info->QualifiersRange.first)
-return std::nullo

[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

2025-06-19 Thread Charles Zablit via lldb-commits

https://github.com/charles-zablit updated 
https://github.com/llvm/llvm-project/pull/144731

>From 3c9a3e5e9af0c9d58783c11490bda473ada84ef3 Mon Sep 17 00:00:00 2001
From: Charles Zablit 
Date: Wed, 18 Jun 2025 16:41:40 +0100
Subject: [PATCH 1/6] [lldb] upgrade HandleFrameFormatVariable callees to
 llvm::Expected

---
 .../Language/CPlusPlus/CPlusPlusLanguage.cpp  | 266 --
 1 file changed, 110 insertions(+), 156 deletions(-)

diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 0f18abb47591d..1810c07652a2b 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -236,199 +236,140 @@ static bool PrettyPrintFunctionNameWithArgs(Stream 
&out_stream,
   return true;
 }
 
-static std::optional
-GetDemangledBasename(const SymbolContext &sc) {
+static llvm::Expected>
+GetAndValidateInfo(const SymbolContext &sc) {
   Mangled mangled = sc.GetPossiblyInlinedFunctionName();
   if (!mangled)
-return std::nullopt;
+return llvm::createStringError("Function does not have a mangled name.");
 
   auto demangled_name = mangled.GetDemangledName().GetStringRef();
   if (demangled_name.empty())
-return std::nullopt;
+return llvm::createStringError("Function does not have a demangled name.");
 
   const std::optional &info = mangled.GetDemangledInfo();
   if (!info)
-return std::nullopt;
+return llvm::createStringError("Function does not have demangled info.");
 
   // Function without a basename is nonsense.
   if (!info->hasBasename())
-return std::nullopt;
+return llvm::createStringError("Info do not have basename range.");
 
-  return demangled_name.slice(info->BasenameRange.first,
-  info->BasenameRange.second);
+  return std::make_pair(demangled_name, *info);
 }
 
-static std::optional
-GetDemangledTemplateArguments(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+static llvm::Expected
+GetDemangledBasename(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  return demangled_name.slice(info.BasenameRange.first,
+  info.BasenameRange.second);
+}
 
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
+static llvm::Expected
+GetDemangledTemplateArguments(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
+
+  auto [demangled_name, info] = *info_or_err;
 
-  if (info->ArgumentsRange.first < info->BasenameRange.second)
-return std::nullopt;
+  if (info.ArgumentsRange.first < info.BasenameRange.second)
+return llvm::createStringError("Arguments in info are invalid.");
 
-  return demangled_name.slice(info->BasenameRange.second,
-  info->ArgumentsRange.first);
+  return demangled_name.slice(info.BasenameRange.second,
+  info.ArgumentsRange.first);
 }
 
-static std::optional
+static llvm::Expected
 GetDemangledReturnTypeLHS(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  if (info.ScopeRange.first >= demangled_name.size())
+return llvm::createStringError("Scope range is invalid.");
 
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
-
-  if (info->ScopeRange.first >= demangled_name.size())
-return std::nullopt;
-
-  return demangled_name.substr(0, info->ScopeRange.first);
+  return demangled_name.substr(0, info.ScopeRange.first);
 }
 
-static std::optional
+static llvm::Expected
 GetDemangledFunctionQualifiers(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::

[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

2025-06-19 Thread Charles Zablit via lldb-commits

https://github.com/charles-zablit updated 
https://github.com/llvm/llvm-project/pull/144731

>From 3c9a3e5e9af0c9d58783c11490bda473ada84ef3 Mon Sep 17 00:00:00 2001
From: Charles Zablit 
Date: Wed, 18 Jun 2025 16:41:40 +0100
Subject: [PATCH 1/7] [lldb] upgrade HandleFrameFormatVariable callees to
 llvm::Expected

---
 .../Language/CPlusPlus/CPlusPlusLanguage.cpp  | 266 --
 1 file changed, 110 insertions(+), 156 deletions(-)

diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 0f18abb47591d..1810c07652a2b 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -236,199 +236,140 @@ static bool PrettyPrintFunctionNameWithArgs(Stream 
&out_stream,
   return true;
 }
 
-static std::optional
-GetDemangledBasename(const SymbolContext &sc) {
+static llvm::Expected>
+GetAndValidateInfo(const SymbolContext &sc) {
   Mangled mangled = sc.GetPossiblyInlinedFunctionName();
   if (!mangled)
-return std::nullopt;
+return llvm::createStringError("Function does not have a mangled name.");
 
   auto demangled_name = mangled.GetDemangledName().GetStringRef();
   if (demangled_name.empty())
-return std::nullopt;
+return llvm::createStringError("Function does not have a demangled name.");
 
   const std::optional &info = mangled.GetDemangledInfo();
   if (!info)
-return std::nullopt;
+return llvm::createStringError("Function does not have demangled info.");
 
   // Function without a basename is nonsense.
   if (!info->hasBasename())
-return std::nullopt;
+return llvm::createStringError("Info do not have basename range.");
 
-  return demangled_name.slice(info->BasenameRange.first,
-  info->BasenameRange.second);
+  return std::make_pair(demangled_name, *info);
 }
 
-static std::optional
-GetDemangledTemplateArguments(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+static llvm::Expected
+GetDemangledBasename(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  return demangled_name.slice(info.BasenameRange.first,
+  info.BasenameRange.second);
+}
 
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
+static llvm::Expected
+GetDemangledTemplateArguments(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
+
+  auto [demangled_name, info] = *info_or_err;
 
-  if (info->ArgumentsRange.first < info->BasenameRange.second)
-return std::nullopt;
+  if (info.ArgumentsRange.first < info.BasenameRange.second)
+return llvm::createStringError("Arguments in info are invalid.");
 
-  return demangled_name.slice(info->BasenameRange.second,
-  info->ArgumentsRange.first);
+  return demangled_name.slice(info.BasenameRange.second,
+  info.ArgumentsRange.first);
 }
 
-static std::optional
+static llvm::Expected
 GetDemangledReturnTypeLHS(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  if (info.ScopeRange.first >= demangled_name.size())
+return llvm::createStringError("Scope range is invalid.");
 
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
-
-  if (info->ScopeRange.first >= demangled_name.size())
-return std::nullopt;
-
-  return demangled_name.substr(0, info->ScopeRange.first);
+  return demangled_name.substr(0, info.ScopeRange.first);
 }
 
-static std::optional
+static llvm::Expected
 GetDemangledFunctionQualifiers(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::

[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

2025-06-19 Thread Charles Zablit via lldb-commits


@@ -236,199 +236,156 @@ static bool PrettyPrintFunctionNameWithArgs(Stream 
&out_stream,
   return true;
 }
 
-static std::optional
-GetDemangledBasename(const SymbolContext &sc) {
+static llvm::Expected>
+GetAndValidateInfo(const SymbolContext &sc) {
   Mangled mangled = sc.GetPossiblyInlinedFunctionName();
   if (!mangled)
-return std::nullopt;
+return llvm::createStringError("Function does not have a mangled name.");
 
   auto demangled_name = mangled.GetDemangledName().GetStringRef();
   if (demangled_name.empty())
-return std::nullopt;
+return llvm::createStringError(
+"Function '%s' does not have a demangled name.",
+mangled.GetMangledName().AsCString(""));
 
   const std::optional &info = mangled.GetDemangledInfo();
   if (!info)
-return std::nullopt;
+return llvm::createStringError(
+"Function '%s' does not have demangled info.", demangled_name.data());
 
   // Function without a basename is nonsense.
   if (!info->hasBasename())
-return std::nullopt;
+return llvm::createStringError(
+"DemangledInfo for '%s does not have basename range.",
+demangled_name.data());
 
-  return demangled_name.slice(info->BasenameRange.first,
-  info->BasenameRange.second);
+  return std::make_pair(demangled_name, *info);
 }
 
-static std::optional
-GetDemangledTemplateArguments(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+static llvm::Expected
+GetDemangledBasename(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  return demangled_name.slice(info.BasenameRange.first,
+  info.BasenameRange.second);
+}
 
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
+static llvm::Expected
+GetDemangledTemplateArguments(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
+
+  auto [demangled_name, info] = *info_or_err;
 
-  if (info->ArgumentsRange.first < info->BasenameRange.second)
-return std::nullopt;
+  if (info.ArgumentsRange.first < info.BasenameRange.second)
+return llvm::createStringError("Arguments range for '%s' is invalid.",
+   demangled_name.data());
 
-  return demangled_name.slice(info->BasenameRange.second,
-  info->ArgumentsRange.first);
+  return demangled_name.slice(info.BasenameRange.second,
+  info.ArgumentsRange.first);
 }
 
-static std::optional
+static llvm::Expected
 GetDemangledReturnTypeLHS(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  if (info.ScopeRange.first >= demangled_name.size())
+return llvm::createStringError(
+"Scope range for '%s' LHS return type is invalid.",
+demangled_name.data());
 
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
-
-  if (info->ScopeRange.first >= demangled_name.size())
-return std::nullopt;
-
-  return demangled_name.substr(0, info->ScopeRange.first);
+  return demangled_name.substr(0, info.ScopeRange.first);
 }
 
-static std::optional
+static llvm::Expected
 GetDemangledFunctionQualifiers(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
-
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
+  if (!info.hasQualifiers())
+return llvm::createStringError("Qualifiers range for '%s' is invalid.",
+   demangled_name.data());
 
-  if (info->QualifiersRange.second < info->QualifiersRange.first)
-return std::nullo

[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

2025-06-19 Thread Charles Zablit via lldb-commits

https://github.com/charles-zablit updated 
https://github.com/llvm/llvm-project/pull/144731

>From 3c9a3e5e9af0c9d58783c11490bda473ada84ef3 Mon Sep 17 00:00:00 2001
From: Charles Zablit 
Date: Wed, 18 Jun 2025 16:41:40 +0100
Subject: [PATCH 1/5] [lldb] upgrade HandleFrameFormatVariable callees to
 llvm::Expected

---
 .../Language/CPlusPlus/CPlusPlusLanguage.cpp  | 266 --
 1 file changed, 110 insertions(+), 156 deletions(-)

diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 0f18abb47591d..1810c07652a2b 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -236,199 +236,140 @@ static bool PrettyPrintFunctionNameWithArgs(Stream 
&out_stream,
   return true;
 }
 
-static std::optional
-GetDemangledBasename(const SymbolContext &sc) {
+static llvm::Expected>
+GetAndValidateInfo(const SymbolContext &sc) {
   Mangled mangled = sc.GetPossiblyInlinedFunctionName();
   if (!mangled)
-return std::nullopt;
+return llvm::createStringError("Function does not have a mangled name.");
 
   auto demangled_name = mangled.GetDemangledName().GetStringRef();
   if (demangled_name.empty())
-return std::nullopt;
+return llvm::createStringError("Function does not have a demangled name.");
 
   const std::optional &info = mangled.GetDemangledInfo();
   if (!info)
-return std::nullopt;
+return llvm::createStringError("Function does not have demangled info.");
 
   // Function without a basename is nonsense.
   if (!info->hasBasename())
-return std::nullopt;
+return llvm::createStringError("Info do not have basename range.");
 
-  return demangled_name.slice(info->BasenameRange.first,
-  info->BasenameRange.second);
+  return std::make_pair(demangled_name, *info);
 }
 
-static std::optional
-GetDemangledTemplateArguments(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+static llvm::Expected
+GetDemangledBasename(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  return demangled_name.slice(info.BasenameRange.first,
+  info.BasenameRange.second);
+}
 
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
+static llvm::Expected
+GetDemangledTemplateArguments(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
+
+  auto [demangled_name, info] = *info_or_err;
 
-  if (info->ArgumentsRange.first < info->BasenameRange.second)
-return std::nullopt;
+  if (info.ArgumentsRange.first < info.BasenameRange.second)
+return llvm::createStringError("Arguments in info are invalid.");
 
-  return demangled_name.slice(info->BasenameRange.second,
-  info->ArgumentsRange.first);
+  return demangled_name.slice(info.BasenameRange.second,
+  info.ArgumentsRange.first);
 }
 
-static std::optional
+static llvm::Expected
 GetDemangledReturnTypeLHS(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  if (info.ScopeRange.first >= demangled_name.size())
+return llvm::createStringError("Scope range is invalid.");
 
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
-
-  if (info->ScopeRange.first >= demangled_name.size())
-return std::nullopt;
-
-  return demangled_name.substr(0, info->ScopeRange.first);
+  return demangled_name.substr(0, info.ScopeRange.first);
 }
 
-static std::optional
+static llvm::Expected
 GetDemangledFunctionQualifiers(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::

[Lldb-commits] [lldb] [lldb] Fix race condition in Process::WaitForProcessToStop() (PR #144919)

2025-06-19 Thread via lldb-commits

https://github.com/athierry-oct created 
https://github.com/llvm/llvm-project/pull/144919

This PR addresses a race condition encountered when using LLDB through the 
Python scripting interface.

I'm relatively new to LLDB, so feedback is very welcome, especially if there's 
a more appropriate way to address this issue.

### Bug Description

When running a script that repeatedly calls 
`debugger.GetListener().WaitForEvent()` in a loop, and at some point invokes 
`process.Kill()` from within that loop to terminate the session, a race 
condition can occur if `process.Kill()` is called around the same time a 
breakpoint is hit.

### Race Condition Details

The issue arises when the following sequence of events happens:

1. The process's **private state** transitions to `stopped` when the breakpoint 
is hit.
2. `process.Kill()` calls `Process::Destroy()`, which invokes 
`Process::WaitForProcessToStop()`. At this point:
   - `private_state = stopped`
   - `public_state = running` (the public state has not yet been updated)
3. The **public stop event** is broadcast **before** the hijack listener is 
installed.
4. As a result, the stop event is delivered to the **non-hijack listener**.
5. The interrupt request sent by `Process::StopForDestroyOrDetach()` is ignored 
because the process is already stopped (`private_state = stopped`).
6. No public stop event reaches the hijack listener.
7. `Process::WaitForProcessToStop()` hangs waiting for a public stop event, but 
the event is never received.
8. `process.Kill()` times out after 20 seconds

### Fix Summary

This patch modifies `Process::WaitForProcessToStop()` to ensure that any 
pending events in the non-hijack listener queue are processed before checking 
the hijack listener. This guarantees that any missed public state change events 
are handled, preventing the hang.


### Additional Context

A discussion of this issue, including a script to reproduce the bug, can be 
found here: 
 [LLDB hangs when killing process at the same time a breakpoint is 
hit](https://discourse.llvm.org/t/lldb-hangs-when-killing-process-at-the-same-time-a-breakpoint-is-hit)

>From dfe59d058645bcf83e7956cec14ad43a7ada5349 Mon Sep 17 00:00:00 2001
From: Adrien Thierry 
Date: Thu, 19 Jun 2025 10:00:46 -0400
Subject: [PATCH] [lldb] Fix race condition in Process::WaitForProcessToStop()

This patch addresses a race condition that can occur when a script using
the Python API calls SBProcess::Kill() around the same time a breakpoint
is hit.

If a stop event is broadcast before the hijack listener is installed, it
may be delivered to the default listener and missed entirely by the
hijack listener. This causes Process::WaitForProcessToStop() to hang
until it times out, waiting for a public stop event that is never
received.

To fix this, Process::WaitForProcessToStop() now checks for pending
events in the non-hijack listener before falling back to the hijack
listener, ensuring that any missed public state change events are
properly handled.
---
 lldb/source/Target/Process.cpp | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 61a3d05bc3746..c75acdb1ecd80 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -683,7 +683,18 @@ StateType Process::WaitForProcessToStop(
 
   while (state != eStateInvalid) {
 EventSP event_sp;
-state = GetStateChangedEvents(event_sp, timeout, hijack_listener_sp);
+
+// A stop event may have been queued in the non-hijack listener before
+// the hijack listener was installed (e.g., if a breakpoint is hit
+// around the same time SBProcess::Kill() is called). Check and process
+// those events first to avoid missing them.
+if (PeekAtStateChangedEvents()) {
+  // Get event from non-hijack listener
+  state = GetStateChangedEvents(event_sp, timeout, nullptr);
+} else {
+  state = GetStateChangedEvents(event_sp, timeout, hijack_listener_sp);
+}
+
 if (event_sp_ptr && event_sp)
   *event_sp_ptr = event_sp;
 

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


[Lldb-commits] [lldb] [lldb] Fix race condition in Process::WaitForProcessToStop() (PR #144919)

2025-06-19 Thread via lldb-commits

github-actions[bot] wrote:



Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this 
page.

If this is not working for you, it is probably because you do not have write 
permissions for the repository. In which case you can instead tag reviewers by 
name in a comment by using `@` followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a 
review by "ping"ing the PR by adding a comment “Ping”. The common courtesy 
"ping" rate is once a week. Please remember that you are asking for valuable 
time from other developers.

If you have further questions, they may be answered by the [LLVM GitHub User 
Guide](https://llvm.org/docs/GitHub.html).

You can also ask questions in a comment on this PR, on the [LLVM 
Discord](https://discord.com/invite/xS7Z362) or on the 
[forums](https://discourse.llvm.org/).

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


[Lldb-commits] [lldb] [lldb] Fix race condition in Process::WaitForProcessToStop() (PR #144919)

2025-06-19 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: None (athierry-oct)


Changes

This PR addresses a race condition encountered when using LLDB through the 
Python scripting interface.

I'm relatively new to LLDB, so feedback is very welcome, especially if there's 
a more appropriate way to address this issue.

### Bug Description

When running a script that repeatedly calls 
`debugger.GetListener().WaitForEvent()` in a loop, and at some point invokes 
`process.Kill()` from within that loop to terminate the session, a race 
condition can occur if `process.Kill()` is called around the same time a 
breakpoint is hit.

### Race Condition Details

The issue arises when the following sequence of events happens:

1. The process's **private state** transitions to `stopped` when the breakpoint 
is hit.
2. `process.Kill()` calls `Process::Destroy()`, which invokes 
`Process::WaitForProcessToStop()`. At this point:
   - `private_state = stopped`
   - `public_state = running` (the public state has not yet been updated)
3. The **public stop event** is broadcast **before** the hijack listener is 
installed.
4. As a result, the stop event is delivered to the **non-hijack listener**.
5. The interrupt request sent by `Process::StopForDestroyOrDetach()` is ignored 
because the process is already stopped (`private_state = stopped`).
6. No public stop event reaches the hijack listener.
7. `Process::WaitForProcessToStop()` hangs waiting for a public stop event, but 
the event is never received.
8. `process.Kill()` times out after 20 seconds

### Fix Summary

This patch modifies `Process::WaitForProcessToStop()` to ensure that any 
pending events in the non-hijack listener queue are processed before checking 
the hijack listener. This guarantees that any missed public state change events 
are handled, preventing the hang.


### Additional Context

A discussion of this issue, including a script to reproduce the bug, can be 
found here: 
 [LLDB hangs when killing process at the same time a breakpoint is 
hit](https://discourse.llvm.org/t/lldb-hangs-when-killing-process-at-the-same-time-a-breakpoint-is-hit)

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


1 Files Affected:

- (modified) lldb/source/Target/Process.cpp (+12-1) 


``diff
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 61a3d05bc3746..c75acdb1ecd80 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -683,7 +683,18 @@ StateType Process::WaitForProcessToStop(
 
   while (state != eStateInvalid) {
 EventSP event_sp;
-state = GetStateChangedEvents(event_sp, timeout, hijack_listener_sp);
+
+// A stop event may have been queued in the non-hijack listener before
+// the hijack listener was installed (e.g., if a breakpoint is hit
+// around the same time SBProcess::Kill() is called). Check and process
+// those events first to avoid missing them.
+if (PeekAtStateChangedEvents()) {
+  // Get event from non-hijack listener
+  state = GetStateChangedEvents(event_sp, timeout, nullptr);
+} else {
+  state = GetStateChangedEvents(event_sp, timeout, hijack_listener_sp);
+}
+
 if (event_sp_ptr && event_sp)
   *event_sp_ptr = event_sp;
 

``




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


[Lldb-commits] [lldb] [lldb] Fix race condition in Process::WaitForProcessToStop() (PR #144919)

2025-06-19 Thread via lldb-commits

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


[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

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


@@ -236,199 +236,156 @@ static bool PrettyPrintFunctionNameWithArgs(Stream 
&out_stream,
   return true;
 }
 
-static std::optional
-GetDemangledBasename(const SymbolContext &sc) {
+static llvm::Expected>
+GetAndValidateInfo(const SymbolContext &sc) {
   Mangled mangled = sc.GetPossiblyInlinedFunctionName();
   if (!mangled)
-return std::nullopt;
+return llvm::createStringError("Function does not have a mangled name.");
 
   auto demangled_name = mangled.GetDemangledName().GetStringRef();
   if (demangled_name.empty())
-return std::nullopt;
+return llvm::createStringError(
+"Function '%s' does not have a demangled name.",
+mangled.GetMangledName().AsCString(""));
 
   const std::optional &info = mangled.GetDemangledInfo();
   if (!info)
-return std::nullopt;
+return llvm::createStringError(
+"Function '%s' does not have demangled info.", demangled_name.data());
 
   // Function without a basename is nonsense.
   if (!info->hasBasename())
-return std::nullopt;
+return llvm::createStringError(
+"DemangledInfo for '%s does not have basename range.",
+demangled_name.data());
 
-  return demangled_name.slice(info->BasenameRange.first,
-  info->BasenameRange.second);
+  return std::make_pair(demangled_name, *info);
 }
 
-static std::optional
-GetDemangledTemplateArguments(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+static llvm::Expected
+GetDemangledBasename(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  return demangled_name.slice(info.BasenameRange.first,
+  info.BasenameRange.second);
+}
 
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
+static llvm::Expected
+GetDemangledTemplateArguments(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
+
+  auto [demangled_name, info] = *info_or_err;
 
-  if (info->ArgumentsRange.first < info->BasenameRange.second)
-return std::nullopt;
+  if (info.ArgumentsRange.first < info.BasenameRange.second)
+return llvm::createStringError("Arguments range for '%s' is invalid.",
+   demangled_name.data());
 
-  return demangled_name.slice(info->BasenameRange.second,
-  info->ArgumentsRange.first);
+  return demangled_name.slice(info.BasenameRange.second,
+  info.ArgumentsRange.first);
 }
 
-static std::optional
+static llvm::Expected
 GetDemangledReturnTypeLHS(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  if (info.ScopeRange.first >= demangled_name.size())

Michael137 wrote:

Can we use `hasScope()` here?

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


[Lldb-commits] [lldb] [lldb] Add DWARFExpressionEntry and GetExpressionEntryAtAddress() to … (PR #144238)

2025-06-19 Thread Abdullah Mohammad Amin via lldb-commits

https://github.com/UltimateForce21 updated 
https://github.com/llvm/llvm-project/pull/144238

>From 8ed8c540e7600d720a63bc2882a81a2c65c11d41 Mon Sep 17 00:00:00 2001
From: ultimateforce21 
Date: Wed, 11 Jun 2025 00:11:09 -0400
Subject: [PATCH 1/2] [lldb] Add DWARFExpressionEntry and
 GetExpressionEntryAtAddress() to DWARFExpressionList

This introduces a new API for retrieving DWARF expression metadata associated 
with variable location entries at a given PC address. It provides the base, 
end, and expression pointer for downstream consumers such as disassembler 
annotations.

Intended for use in richer instruction annotations in Instruction::Dump().
---
 .../lldb/Expression/DWARFExpressionList.h | 12 +++
 .../source/Expression/DWARFExpressionList.cpp | 21 +++
 2 files changed, 33 insertions(+)

diff --git a/lldb/include/lldb/Expression/DWARFExpressionList.h 
b/lldb/include/lldb/Expression/DWARFExpressionList.h
index d8f8ec247ed56..a329b37393018 100644
--- a/lldb/include/lldb/Expression/DWARFExpressionList.h
+++ b/lldb/include/lldb/Expression/DWARFExpressionList.h
@@ -59,6 +59,18 @@ class DWARFExpressionList {
 
   lldb::addr_t GetFuncFileAddress() { return m_func_file_addr; }
 
+  /// Represents an entry in the DWARFExpressionList with all needed metadata
+  struct DWARFExpressionEntry {
+lldb::addr_t base;
+lldb::addr_t end;
+const DWARFExpression *expr;
+  };
+
+  /// Returns the entry (base, end, data) for a given PC address
+  llvm::Expected
+  GetExpressionEntryAtAddress(lldb::addr_t func_load_addr,
+  lldb::addr_t load_addr) const;
+
   const DWARFExpression *GetExpressionAtAddress(lldb::addr_t func_load_addr,
 lldb::addr_t load_addr) const;
 
diff --git a/lldb/source/Expression/DWARFExpressionList.cpp 
b/lldb/source/Expression/DWARFExpressionList.cpp
index 04592a1eb7ff4..b55bc7120c4af 100644
--- a/lldb/source/Expression/DWARFExpressionList.cpp
+++ b/lldb/source/Expression/DWARFExpressionList.cpp
@@ -53,6 +53,27 @@ bool DWARFExpressionList::ContainsAddress(lldb::addr_t 
func_load_addr,
   return GetExpressionAtAddress(func_load_addr, addr) != nullptr;
 }
 
+llvm::Expected
+DWARFExpressionList::GetExpressionEntryAtAddress(lldb::addr_t func_load_addr,
+ lldb::addr_t load_addr) const 
{
+  if (const DWARFExpression *expr = GetAlwaysValidExpr()) {
+return DWARFExpressionEntry{0, LLDB_INVALID_ADDRESS, expr};
+  }
+
+  if (func_load_addr == LLDB_INVALID_ADDRESS)
+func_load_addr = m_func_file_addr;
+
+  addr_t addr = load_addr - func_load_addr + m_func_file_addr;
+  uint32_t index = m_exprs.FindEntryIndexThatContains(addr);
+  if (index == UINT32_MAX) {
+return llvm::createStringError(llvm::inconvertibleErrorCode(),
+   "No DWARF expression found for address 
0x%llx", addr);
+  }
+
+  const Entry &entry = *m_exprs.GetEntryAtIndex(index);
+  return DWARFExpressionEntry{entry.base, entry.GetRangeEnd(), &entry.data};
+}
+
 const DWARFExpression *
 DWARFExpressionList::GetExpressionAtAddress(lldb::addr_t func_load_addr,
 lldb::addr_t load_addr) const {

>From 1db5002a69dba4f88aaac56d61520b7b4b214b01 Mon Sep 17 00:00:00 2001
From: Abdullah Mohammad Amin
 <67847674+ultimateforc...@users.noreply.github.com>
Date: Thu, 19 Jun 2025 11:55:35 -0400
Subject: [PATCH 2/2] Update lldb/include/lldb/Expression/DWARFExpressionList.h

Co-authored-by: Jonas Devlieghere 
---
 lldb/include/lldb/Expression/DWARFExpressionList.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/include/lldb/Expression/DWARFExpressionList.h 
b/lldb/include/lldb/Expression/DWARFExpressionList.h
index a329b37393018..89e55ffc07659 100644
--- a/lldb/include/lldb/Expression/DWARFExpressionList.h
+++ b/lldb/include/lldb/Expression/DWARFExpressionList.h
@@ -59,7 +59,7 @@ class DWARFExpressionList {
 
   lldb::addr_t GetFuncFileAddress() { return m_func_file_addr; }
 
-  /// Represents an entry in the DWARFExpressionList with all needed metadata
+  /// Represents an entry in the DWARFExpressionList with all needed metadata.
   struct DWARFExpressionEntry {
 lldb::addr_t base;
 lldb::addr_t end;

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


[Lldb-commits] [lldb] [lldb] Add DWARFExpressionEntry and GetExpressionEntryAtAddress() to … (PR #144238)

2025-06-19 Thread Abdullah Mohammad Amin via lldb-commits

https://github.com/UltimateForce21 updated 
https://github.com/llvm/llvm-project/pull/144238

>From 8ed8c540e7600d720a63bc2882a81a2c65c11d41 Mon Sep 17 00:00:00 2001
From: ultimateforce21 
Date: Wed, 11 Jun 2025 00:11:09 -0400
Subject: [PATCH 1/3] [lldb] Add DWARFExpressionEntry and
 GetExpressionEntryAtAddress() to DWARFExpressionList

This introduces a new API for retrieving DWARF expression metadata associated 
with variable location entries at a given PC address. It provides the base, 
end, and expression pointer for downstream consumers such as disassembler 
annotations.

Intended for use in richer instruction annotations in Instruction::Dump().
---
 .../lldb/Expression/DWARFExpressionList.h | 12 +++
 .../source/Expression/DWARFExpressionList.cpp | 21 +++
 2 files changed, 33 insertions(+)

diff --git a/lldb/include/lldb/Expression/DWARFExpressionList.h 
b/lldb/include/lldb/Expression/DWARFExpressionList.h
index d8f8ec247ed56..a329b37393018 100644
--- a/lldb/include/lldb/Expression/DWARFExpressionList.h
+++ b/lldb/include/lldb/Expression/DWARFExpressionList.h
@@ -59,6 +59,18 @@ class DWARFExpressionList {
 
   lldb::addr_t GetFuncFileAddress() { return m_func_file_addr; }
 
+  /// Represents an entry in the DWARFExpressionList with all needed metadata
+  struct DWARFExpressionEntry {
+lldb::addr_t base;
+lldb::addr_t end;
+const DWARFExpression *expr;
+  };
+
+  /// Returns the entry (base, end, data) for a given PC address
+  llvm::Expected
+  GetExpressionEntryAtAddress(lldb::addr_t func_load_addr,
+  lldb::addr_t load_addr) const;
+
   const DWARFExpression *GetExpressionAtAddress(lldb::addr_t func_load_addr,
 lldb::addr_t load_addr) const;
 
diff --git a/lldb/source/Expression/DWARFExpressionList.cpp 
b/lldb/source/Expression/DWARFExpressionList.cpp
index 04592a1eb7ff4..b55bc7120c4af 100644
--- a/lldb/source/Expression/DWARFExpressionList.cpp
+++ b/lldb/source/Expression/DWARFExpressionList.cpp
@@ -53,6 +53,27 @@ bool DWARFExpressionList::ContainsAddress(lldb::addr_t 
func_load_addr,
   return GetExpressionAtAddress(func_load_addr, addr) != nullptr;
 }
 
+llvm::Expected
+DWARFExpressionList::GetExpressionEntryAtAddress(lldb::addr_t func_load_addr,
+ lldb::addr_t load_addr) const 
{
+  if (const DWARFExpression *expr = GetAlwaysValidExpr()) {
+return DWARFExpressionEntry{0, LLDB_INVALID_ADDRESS, expr};
+  }
+
+  if (func_load_addr == LLDB_INVALID_ADDRESS)
+func_load_addr = m_func_file_addr;
+
+  addr_t addr = load_addr - func_load_addr + m_func_file_addr;
+  uint32_t index = m_exprs.FindEntryIndexThatContains(addr);
+  if (index == UINT32_MAX) {
+return llvm::createStringError(llvm::inconvertibleErrorCode(),
+   "No DWARF expression found for address 
0x%llx", addr);
+  }
+
+  const Entry &entry = *m_exprs.GetEntryAtIndex(index);
+  return DWARFExpressionEntry{entry.base, entry.GetRangeEnd(), &entry.data};
+}
+
 const DWARFExpression *
 DWARFExpressionList::GetExpressionAtAddress(lldb::addr_t func_load_addr,
 lldb::addr_t load_addr) const {

>From 1db5002a69dba4f88aaac56d61520b7b4b214b01 Mon Sep 17 00:00:00 2001
From: Abdullah Mohammad Amin
 <67847674+ultimateforc...@users.noreply.github.com>
Date: Thu, 19 Jun 2025 11:55:35 -0400
Subject: [PATCH 2/3] Update lldb/include/lldb/Expression/DWARFExpressionList.h

Co-authored-by: Jonas Devlieghere 
---
 lldb/include/lldb/Expression/DWARFExpressionList.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/include/lldb/Expression/DWARFExpressionList.h 
b/lldb/include/lldb/Expression/DWARFExpressionList.h
index a329b37393018..89e55ffc07659 100644
--- a/lldb/include/lldb/Expression/DWARFExpressionList.h
+++ b/lldb/include/lldb/Expression/DWARFExpressionList.h
@@ -59,7 +59,7 @@ class DWARFExpressionList {
 
   lldb::addr_t GetFuncFileAddress() { return m_func_file_addr; }
 
-  /// Represents an entry in the DWARFExpressionList with all needed metadata
+  /// Represents an entry in the DWARFExpressionList with all needed metadata.
   struct DWARFExpressionEntry {
 lldb::addr_t base;
 lldb::addr_t end;

>From a26010b06e5067b8b3b223cbd76e8848ecb9a289 Mon Sep 17 00:00:00 2001
From: Abdullah Mohammad Amin
 <67847674+ultimateforc...@users.noreply.github.com>
Date: Thu, 19 Jun 2025 11:58:28 -0400
Subject: [PATCH 3/3] Update lldb/include/lldb/Expression/DWARFExpressionList.h

Updated comment for GetExpressionEntryAtAddress to directly refer to struct 
DWARFExpressionEntry

Co-authored-by: Jonas Devlieghere 
---
 lldb/include/lldb/Expression/DWARFExpressionList.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/include/lldb/Expression/DWARFExpressionList.h 
b/lldb/include/lldb/Expression/DWARFExpressionList.h
index 89e55ffc07659..f6a269809decc 100644
--- a/lldb/includ

[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

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


@@ -236,199 +236,156 @@ static bool PrettyPrintFunctionNameWithArgs(Stream 
&out_stream,
   return true;
 }
 
-static std::optional
-GetDemangledBasename(const SymbolContext &sc) {
+static llvm::Expected>
+GetAndValidateInfo(const SymbolContext &sc) {
   Mangled mangled = sc.GetPossiblyInlinedFunctionName();
   if (!mangled)
-return std::nullopt;
+return llvm::createStringError("Function does not have a mangled name.");
 
   auto demangled_name = mangled.GetDemangledName().GetStringRef();
   if (demangled_name.empty())
-return std::nullopt;
+return llvm::createStringError(
+"Function '%s' does not have a demangled name.",
+mangled.GetMangledName().AsCString(""));
 
   const std::optional &info = mangled.GetDemangledInfo();
   if (!info)
-return std::nullopt;
+return llvm::createStringError(
+"Function '%s' does not have demangled info.", demangled_name.data());
 
   // Function without a basename is nonsense.
   if (!info->hasBasename())
-return std::nullopt;
+return llvm::createStringError(
+"DemangledInfo for '%s does not have basename range.",
+demangled_name.data());
 
-  return demangled_name.slice(info->BasenameRange.first,
-  info->BasenameRange.second);
+  return std::make_pair(demangled_name, *info);
 }
 
-static std::optional
-GetDemangledTemplateArguments(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+static llvm::Expected
+GetDemangledBasename(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  return demangled_name.slice(info.BasenameRange.first,
+  info.BasenameRange.second);
+}
 
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
+static llvm::Expected
+GetDemangledTemplateArguments(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
+
+  auto [demangled_name, info] = *info_or_err;
 
-  if (info->ArgumentsRange.first < info->BasenameRange.second)
-return std::nullopt;
+  if (info.ArgumentsRange.first < info.BasenameRange.second)
+return llvm::createStringError("Arguments range for '%s' is invalid.",
+   demangled_name.data());
 
-  return demangled_name.slice(info->BasenameRange.second,
-  info->ArgumentsRange.first);
+  return demangled_name.slice(info.BasenameRange.second,
+  info.ArgumentsRange.first);
 }
 
-static std::optional
+static llvm::Expected
 GetDemangledReturnTypeLHS(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  if (info.ScopeRange.first >= demangled_name.size())
+return llvm::createStringError(
+"Scope range for '%s' LHS return type is invalid.",
+demangled_name.data());
 
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
-
-  if (info->ScopeRange.first >= demangled_name.size())
-return std::nullopt;
-
-  return demangled_name.substr(0, info->ScopeRange.first);
+  return demangled_name.substr(0, info.ScopeRange.first);
 }
 
-static std::optional
+static llvm::Expected
 GetDemangledFunctionQualifiers(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
-
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
+  if (!info.hasQualifiers())
+return llvm::createStringError("Qualifiers range for '%s' is invalid.",
+   demangled_name.data());
 
-  if (info->QualifiersRange.second < info->QualifiersRange.first)
-return std::nullo

[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

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


@@ -236,199 +236,156 @@ static bool PrettyPrintFunctionNameWithArgs(Stream 
&out_stream,
   return true;
 }
 
-static std::optional
-GetDemangledBasename(const SymbolContext &sc) {
+static llvm::Expected>
+GetAndValidateInfo(const SymbolContext &sc) {
   Mangled mangled = sc.GetPossiblyInlinedFunctionName();
   if (!mangled)
-return std::nullopt;
+return llvm::createStringError("Function does not have a mangled name.");
 
   auto demangled_name = mangled.GetDemangledName().GetStringRef();
   if (demangled_name.empty())
-return std::nullopt;
+return llvm::createStringError(
+"Function '%s' does not have a demangled name.",
+mangled.GetMangledName().AsCString(""));
 
   const std::optional &info = mangled.GetDemangledInfo();
   if (!info)
-return std::nullopt;
+return llvm::createStringError(
+"Function '%s' does not have demangled info.", demangled_name.data());
 
   // Function without a basename is nonsense.
   if (!info->hasBasename())
-return std::nullopt;
+return llvm::createStringError(
+"DemangledInfo for '%s does not have basename range.",
+demangled_name.data());
 
-  return demangled_name.slice(info->BasenameRange.first,
-  info->BasenameRange.second);
+  return std::make_pair(demangled_name, *info);
 }
 
-static std::optional
-GetDemangledTemplateArguments(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+static llvm::Expected
+GetDemangledBasename(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  return demangled_name.slice(info.BasenameRange.first,
+  info.BasenameRange.second);
+}
 
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
+static llvm::Expected
+GetDemangledTemplateArguments(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
+
+  auto [demangled_name, info] = *info_or_err;
 
-  if (info->ArgumentsRange.first < info->BasenameRange.second)
-return std::nullopt;
+  if (info.ArgumentsRange.first < info.BasenameRange.second)
+return llvm::createStringError("Arguments range for '%s' is invalid.",
+   demangled_name.data());
 
-  return demangled_name.slice(info->BasenameRange.second,
-  info->ArgumentsRange.first);
+  return demangled_name.slice(info.BasenameRange.second,
+  info.ArgumentsRange.first);
 }
 
-static std::optional
+static llvm::Expected
 GetDemangledReturnTypeLHS(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  if (info.ScopeRange.first >= demangled_name.size())

Michael137 wrote:

Ah nvm, even without a scope we could have a LHS return

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


[Lldb-commits] [lldb] [lldb] Add DWARFExpressionEntry and GetExpressionEntryAtAddress() to … (PR #144238)

2025-06-19 Thread Abdullah Mohammad Amin via lldb-commits

https://github.com/UltimateForce21 updated 
https://github.com/llvm/llvm-project/pull/144238

>From 8ed8c540e7600d720a63bc2882a81a2c65c11d41 Mon Sep 17 00:00:00 2001
From: ultimateforce21 
Date: Wed, 11 Jun 2025 00:11:09 -0400
Subject: [PATCH 1/4] [lldb] Add DWARFExpressionEntry and
 GetExpressionEntryAtAddress() to DWARFExpressionList

This introduces a new API for retrieving DWARF expression metadata associated 
with variable location entries at a given PC address. It provides the base, 
end, and expression pointer for downstream consumers such as disassembler 
annotations.

Intended for use in richer instruction annotations in Instruction::Dump().
---
 .../lldb/Expression/DWARFExpressionList.h | 12 +++
 .../source/Expression/DWARFExpressionList.cpp | 21 +++
 2 files changed, 33 insertions(+)

diff --git a/lldb/include/lldb/Expression/DWARFExpressionList.h 
b/lldb/include/lldb/Expression/DWARFExpressionList.h
index d8f8ec247ed56..a329b37393018 100644
--- a/lldb/include/lldb/Expression/DWARFExpressionList.h
+++ b/lldb/include/lldb/Expression/DWARFExpressionList.h
@@ -59,6 +59,18 @@ class DWARFExpressionList {
 
   lldb::addr_t GetFuncFileAddress() { return m_func_file_addr; }
 
+  /// Represents an entry in the DWARFExpressionList with all needed metadata
+  struct DWARFExpressionEntry {
+lldb::addr_t base;
+lldb::addr_t end;
+const DWARFExpression *expr;
+  };
+
+  /// Returns the entry (base, end, data) for a given PC address
+  llvm::Expected
+  GetExpressionEntryAtAddress(lldb::addr_t func_load_addr,
+  lldb::addr_t load_addr) const;
+
   const DWARFExpression *GetExpressionAtAddress(lldb::addr_t func_load_addr,
 lldb::addr_t load_addr) const;
 
diff --git a/lldb/source/Expression/DWARFExpressionList.cpp 
b/lldb/source/Expression/DWARFExpressionList.cpp
index 04592a1eb7ff4..b55bc7120c4af 100644
--- a/lldb/source/Expression/DWARFExpressionList.cpp
+++ b/lldb/source/Expression/DWARFExpressionList.cpp
@@ -53,6 +53,27 @@ bool DWARFExpressionList::ContainsAddress(lldb::addr_t 
func_load_addr,
   return GetExpressionAtAddress(func_load_addr, addr) != nullptr;
 }
 
+llvm::Expected
+DWARFExpressionList::GetExpressionEntryAtAddress(lldb::addr_t func_load_addr,
+ lldb::addr_t load_addr) const 
{
+  if (const DWARFExpression *expr = GetAlwaysValidExpr()) {
+return DWARFExpressionEntry{0, LLDB_INVALID_ADDRESS, expr};
+  }
+
+  if (func_load_addr == LLDB_INVALID_ADDRESS)
+func_load_addr = m_func_file_addr;
+
+  addr_t addr = load_addr - func_load_addr + m_func_file_addr;
+  uint32_t index = m_exprs.FindEntryIndexThatContains(addr);
+  if (index == UINT32_MAX) {
+return llvm::createStringError(llvm::inconvertibleErrorCode(),
+   "No DWARF expression found for address 
0x%llx", addr);
+  }
+
+  const Entry &entry = *m_exprs.GetEntryAtIndex(index);
+  return DWARFExpressionEntry{entry.base, entry.GetRangeEnd(), &entry.data};
+}
+
 const DWARFExpression *
 DWARFExpressionList::GetExpressionAtAddress(lldb::addr_t func_load_addr,
 lldb::addr_t load_addr) const {

>From 1db5002a69dba4f88aaac56d61520b7b4b214b01 Mon Sep 17 00:00:00 2001
From: Abdullah Mohammad Amin
 <67847674+ultimateforc...@users.noreply.github.com>
Date: Thu, 19 Jun 2025 11:55:35 -0400
Subject: [PATCH 2/4] Update lldb/include/lldb/Expression/DWARFExpressionList.h

Co-authored-by: Jonas Devlieghere 
---
 lldb/include/lldb/Expression/DWARFExpressionList.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/include/lldb/Expression/DWARFExpressionList.h 
b/lldb/include/lldb/Expression/DWARFExpressionList.h
index a329b37393018..89e55ffc07659 100644
--- a/lldb/include/lldb/Expression/DWARFExpressionList.h
+++ b/lldb/include/lldb/Expression/DWARFExpressionList.h
@@ -59,7 +59,7 @@ class DWARFExpressionList {
 
   lldb::addr_t GetFuncFileAddress() { return m_func_file_addr; }
 
-  /// Represents an entry in the DWARFExpressionList with all needed metadata
+  /// Represents an entry in the DWARFExpressionList with all needed metadata.
   struct DWARFExpressionEntry {
 lldb::addr_t base;
 lldb::addr_t end;

>From a26010b06e5067b8b3b223cbd76e8848ecb9a289 Mon Sep 17 00:00:00 2001
From: Abdullah Mohammad Amin
 <67847674+ultimateforc...@users.noreply.github.com>
Date: Thu, 19 Jun 2025 11:58:28 -0400
Subject: [PATCH 3/4] Update lldb/include/lldb/Expression/DWARFExpressionList.h

Updated comment for GetExpressionEntryAtAddress to directly refer to struct 
DWARFExpressionEntry

Co-authored-by: Jonas Devlieghere 
---
 lldb/include/lldb/Expression/DWARFExpressionList.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/include/lldb/Expression/DWARFExpressionList.h 
b/lldb/include/lldb/Expression/DWARFExpressionList.h
index 89e55ffc07659..f6a269809decc 100644
--- a/lldb/includ

[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

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


@@ -236,199 +236,156 @@ static bool PrettyPrintFunctionNameWithArgs(Stream 
&out_stream,
   return true;
 }
 
-static std::optional
-GetDemangledBasename(const SymbolContext &sc) {
+static llvm::Expected>
+GetAndValidateInfo(const SymbolContext &sc) {
   Mangled mangled = sc.GetPossiblyInlinedFunctionName();
   if (!mangled)
-return std::nullopt;
+return llvm::createStringError("Function does not have a mangled name.");
 
   auto demangled_name = mangled.GetDemangledName().GetStringRef();
   if (demangled_name.empty())
-return std::nullopt;
+return llvm::createStringError(
+"Function '%s' does not have a demangled name.",
+mangled.GetMangledName().AsCString(""));
 
   const std::optional &info = mangled.GetDemangledInfo();
   if (!info)
-return std::nullopt;
+return llvm::createStringError(
+"Function '%s' does not have demangled info.", demangled_name.data());
 
   // Function without a basename is nonsense.
   if (!info->hasBasename())
-return std::nullopt;
+return llvm::createStringError(
+"DemangledInfo for '%s does not have basename range.",
+demangled_name.data());
 
-  return demangled_name.slice(info->BasenameRange.first,
-  info->BasenameRange.second);
+  return std::make_pair(demangled_name, *info);
 }
 
-static std::optional
-GetDemangledTemplateArguments(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+static llvm::Expected
+GetDemangledBasename(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  return demangled_name.slice(info.BasenameRange.first,
+  info.BasenameRange.second);
+}
 
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
+static llvm::Expected
+GetDemangledTemplateArguments(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
+
+  auto [demangled_name, info] = *info_or_err;
 
-  if (info->ArgumentsRange.first < info->BasenameRange.second)
-return std::nullopt;
+  if (info.ArgumentsRange.first < info.BasenameRange.second)
+return llvm::createStringError("Arguments range for '%s' is invalid.",
+   demangled_name.data());
 
-  return demangled_name.slice(info->BasenameRange.second,
-  info->ArgumentsRange.first);
+  return demangled_name.slice(info.BasenameRange.second,
+  info.ArgumentsRange.first);
 }
 
-static std::optional
+static llvm::Expected
 GetDemangledReturnTypeLHS(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  if (info.ScopeRange.first >= demangled_name.size())
+return llvm::createStringError(
+"Scope range for '%s' LHS return type is invalid.",
+demangled_name.data());
 
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
-
-  if (info->ScopeRange.first >= demangled_name.size())
-return std::nullopt;
-
-  return demangled_name.substr(0, info->ScopeRange.first);
+  return demangled_name.substr(0, info.ScopeRange.first);
 }
 
-static std::optional
+static llvm::Expected
 GetDemangledFunctionQualifiers(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
-
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
+  if (!info.hasQualifiers())
+return llvm::createStringError("Qualifiers range for '%s' is invalid.",
+   demangled_name.data());
 
-  if (info->QualifiersRange.second < info->QualifiersRange.first)
-return std::nullo

[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

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

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

Just left a couple follow-up comments. Otherwise LGTM!

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


[Lldb-commits] [lldb] [lldb] Fix race condition in Process::WaitForProcessToStop() (PR #144919)

2025-06-19 Thread via lldb-commits

athierry-oct wrote:

@jimingham tagging you since you were in the discussion in [LLDB hangs when 
killing process at the same time a breakpoint is 
hit](https://discourse.llvm.org/t/lldb-hangs-when-killing-process-at-the-same-time-a-breakpoint-is-hit)

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


[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

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


@@ -236,199 +236,141 @@ static bool PrettyPrintFunctionNameWithArgs(Stream 
&out_stream,
   return true;
 }
 
-static std::optional
-GetDemangledBasename(const SymbolContext &sc) {
+static llvm::Expected>
+GetAndValidateInfo(const SymbolContext &sc) {
   Mangled mangled = sc.GetPossiblyInlinedFunctionName();
   if (!mangled)
-return std::nullopt;
+return llvm::createStringError("Function does not have a mangled name.");
 
   auto demangled_name = mangled.GetDemangledName().GetStringRef();
   if (demangled_name.empty())
-return std::nullopt;
+return llvm::createStringError("Function does not have a demangled name.");
 
   const std::optional &info = mangled.GetDemangledInfo();
   if (!info)
-return std::nullopt;
+return llvm::createStringError("Function does not have demangled info.");
 
   // Function without a basename is nonsense.
   if (!info->hasBasename())
-return std::nullopt;
+return llvm::createStringError("Info do not have basename range.");

Michael137 wrote:

Oh nvm, they already are :)

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


[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

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


@@ -236,199 +236,141 @@ static bool PrettyPrintFunctionNameWithArgs(Stream 
&out_stream,
   return true;
 }
 
-static std::optional
-GetDemangledBasename(const SymbolContext &sc) {
+static llvm::Expected>
+GetAndValidateInfo(const SymbolContext &sc) {
   Mangled mangled = sc.GetPossiblyInlinedFunctionName();
   if (!mangled)
-return std::nullopt;
+return llvm::createStringError("Function does not have a mangled name.");
 
   auto demangled_name = mangled.GetDemangledName().GetStringRef();
   if (demangled_name.empty())
-return std::nullopt;
+return llvm::createStringError("Function does not have a demangled name.");

Michael137 wrote:

```suggestion
return llvm::createStringError("Function '%s' does not have a demangled 
name.", mangled.GetMangledName().AsCString(""));
```

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


[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

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


@@ -236,199 +236,141 @@ static bool PrettyPrintFunctionNameWithArgs(Stream 
&out_stream,
   return true;
 }
 
-static std::optional
-GetDemangledBasename(const SymbolContext &sc) {
+static llvm::Expected>
+GetAndValidateInfo(const SymbolContext &sc) {
   Mangled mangled = sc.GetPossiblyInlinedFunctionName();
   if (!mangled)
-return std::nullopt;
+return llvm::createStringError("Function does not have a mangled name.");
 
   auto demangled_name = mangled.GetDemangledName().GetStringRef();
   if (demangled_name.empty())
-return std::nullopt;
+return llvm::createStringError("Function does not have a demangled name.");
 
   const std::optional &info = mangled.GetDemangledInfo();
   if (!info)
-return std::nullopt;
+return llvm::createStringError("Function does not have demangled info.");
 
   // Function without a basename is nonsense.
   if (!info->hasBasename())
-return std::nullopt;
+return llvm::createStringError("Info do not have basename range.");

Michael137 wrote:

Can we make all these error messages more unique? So we can tell by looking at 
the log which branch was taken here?

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


[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

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


@@ -236,199 +236,141 @@ static bool PrettyPrintFunctionNameWithArgs(Stream 
&out_stream,
   return true;
 }
 
-static std::optional
-GetDemangledBasename(const SymbolContext &sc) {
+static llvm::Expected>
+GetAndValidateInfo(const SymbolContext &sc) {
   Mangled mangled = sc.GetPossiblyInlinedFunctionName();
   if (!mangled)
-return std::nullopt;
+return llvm::createStringError("Function does not have a mangled name.");
 
   auto demangled_name = mangled.GetDemangledName().GetStringRef();
   if (demangled_name.empty())
-return std::nullopt;
+return llvm::createStringError("Function does not have a demangled name.");
 
   const std::optional &info = mangled.GetDemangledInfo();
   if (!info)
-return std::nullopt;
+return llvm::createStringError("Function does not have demangled info.");
 
   // Function without a basename is nonsense.
   if (!info->hasBasename())
-return std::nullopt;
+return llvm::createStringError("Info do not have basename range.");
 
-  return demangled_name.slice(info->BasenameRange.first,
-  info->BasenameRange.second);
+  return std::make_pair(demangled_name, *info);
 }
 
-static std::optional
-GetDemangledTemplateArguments(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+static llvm::Expected
+GetDemangledBasename(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  return demangled_name.slice(info.BasenameRange.first,
+  info.BasenameRange.second);
+}
 
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
+static llvm::Expected
+GetDemangledTemplateArguments(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
+
+  auto [demangled_name, info] = *info_or_err;
 
-  if (info->ArgumentsRange.first < info->BasenameRange.second)
-return std::nullopt;
+  if (info.ArgumentsRange.first < info.BasenameRange.second)
+return llvm::createStringError("Arguments in info are invalid.");
 
-  return demangled_name.slice(info->BasenameRange.second,
-  info->ArgumentsRange.first);
+  return demangled_name.slice(info.BasenameRange.second,
+  info.ArgumentsRange.first);
 }
 
-static std::optional
+static llvm::Expected
 GetDemangledReturnTypeLHS(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  if (info.ScopeRange.first >= demangled_name.size())
+return llvm::createStringError("Scope range is invalid.");

Michael137 wrote:

```suggestion
return llvm::createStringError("Scope range for '%s' is invalid.", 
demangled_name.data());
```

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


[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

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


@@ -236,199 +236,141 @@ static bool PrettyPrintFunctionNameWithArgs(Stream 
&out_stream,
   return true;
 }
 
-static std::optional
-GetDemangledBasename(const SymbolContext &sc) {
+static llvm::Expected>
+GetAndValidateInfo(const SymbolContext &sc) {
   Mangled mangled = sc.GetPossiblyInlinedFunctionName();
   if (!mangled)
-return std::nullopt;
+return llvm::createStringError("Function does not have a mangled name.");
 
   auto demangled_name = mangled.GetDemangledName().GetStringRef();
   if (demangled_name.empty())
-return std::nullopt;
+return llvm::createStringError("Function does not have a demangled name.");
 
   const std::optional &info = mangled.GetDemangledInfo();
   if (!info)
-return std::nullopt;
+return llvm::createStringError("Function does not have demangled info.");
 
   // Function without a basename is nonsense.
   if (!info->hasBasename())
-return std::nullopt;
+return llvm::createStringError("Info do not have basename range.");

Michael137 wrote:

```suggestion
return llvm::createStringError("DemangledInfo for '%s' do not have basename 
range.", demangled_name.data());
```

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


[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

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


@@ -236,199 +236,141 @@ static bool PrettyPrintFunctionNameWithArgs(Stream 
&out_stream,
   return true;
 }
 
-static std::optional
-GetDemangledBasename(const SymbolContext &sc) {
+static llvm::Expected>
+GetAndValidateInfo(const SymbolContext &sc) {
   Mangled mangled = sc.GetPossiblyInlinedFunctionName();
   if (!mangled)
-return std::nullopt;
+return llvm::createStringError("Function does not have a mangled name.");
 
   auto demangled_name = mangled.GetDemangledName().GetStringRef();
   if (demangled_name.empty())
-return std::nullopt;
+return llvm::createStringError("Function does not have a demangled name.");
 
   const std::optional &info = mangled.GetDemangledInfo();
   if (!info)
-return std::nullopt;
+return llvm::createStringError("Function does not have demangled info.");

Michael137 wrote:

```suggestion
return llvm::createStringError("Function '%s' does not have demangled 
info.", demangled_name.data());
```

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


[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

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


@@ -236,199 +236,141 @@ static bool PrettyPrintFunctionNameWithArgs(Stream 
&out_stream,
   return true;
 }
 
-static std::optional
-GetDemangledBasename(const SymbolContext &sc) {
+static llvm::Expected>
+GetAndValidateInfo(const SymbolContext &sc) {
   Mangled mangled = sc.GetPossiblyInlinedFunctionName();
   if (!mangled)
-return std::nullopt;
+return llvm::createStringError("Function does not have a mangled name.");
 
   auto demangled_name = mangled.GetDemangledName().GetStringRef();
   if (demangled_name.empty())
-return std::nullopt;
+return llvm::createStringError("Function does not have a demangled name.");
 
   const std::optional &info = mangled.GetDemangledInfo();
   if (!info)
-return std::nullopt;
+return llvm::createStringError("Function does not have demangled info.");
 
   // Function without a basename is nonsense.
   if (!info->hasBasename())
-return std::nullopt;
+return llvm::createStringError("Info do not have basename range.");
 
-  return demangled_name.slice(info->BasenameRange.first,
-  info->BasenameRange.second);
+  return std::make_pair(demangled_name, *info);
 }
 
-static std::optional
-GetDemangledTemplateArguments(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+static llvm::Expected
+GetDemangledBasename(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  return demangled_name.slice(info.BasenameRange.first,
+  info.BasenameRange.second);
+}
 
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
+static llvm::Expected
+GetDemangledTemplateArguments(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
+
+  auto [demangled_name, info] = *info_or_err;
 
-  if (info->ArgumentsRange.first < info->BasenameRange.second)
-return std::nullopt;
+  if (info.ArgumentsRange.first < info.BasenameRange.second)
+return llvm::createStringError("Arguments in info are invalid.");
 
-  return demangled_name.slice(info->BasenameRange.second,
-  info->ArgumentsRange.first);
+  return demangled_name.slice(info.BasenameRange.second,
+  info.ArgumentsRange.first);
 }
 
-static std::optional
+static llvm::Expected
 GetDemangledReturnTypeLHS(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  if (info.ScopeRange.first >= demangled_name.size())
+return llvm::createStringError("Scope range is invalid.");

Michael137 wrote:

Can you similarly include the demangled_name in the error message elsewhere too?

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


[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

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

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


[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

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


@@ -1954,32 +1896,41 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
 FormatEntity::Entry::Type type, Stream &s) {
   switch (type) {
   case FormatEntity::Entry::Type::FunctionScope: {
-std::optional scope = GetDemangledScope(sc);
-if (!scope)
+auto scope_or_err = GetDemangledScope(sc);
+if (!scope_or_err) {
+  LLDB_LOG_ERROR(GetLog(LLDBLog::Language), scope_or_err.takeError(),
+ "Failed to retrieve scope: {0}");
   return false;
+}
 
-s << *scope;
+s << *scope_or_err;
 
 return true;
   }
 
   case FormatEntity::Entry::Type::FunctionBasename: {
-std::optional name = GetDemangledBasename(sc);
-if (!name)
+auto name_or_err = GetDemangledBasename(sc);
+if (!name_or_err) {
+  LLDB_LOG_ERROR(GetLog(LLDBLog::Language), name_or_err.takeError(),
+ "Failed to retrieve basename: {0}");

Michael137 wrote:

```suggestion
 "Failed to handle ${function.basename}: {0}");
```
And do this for the other messages in this switch too?

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


[Lldb-commits] [lldb] [lldb] add has methods to all DemangledNameInfo attributes (PR #144549)

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

Michael137 wrote:

Agreed, if we can somehow call these in `MangledTest.cpp`, that'd be great

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


[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

2025-06-19 Thread Charles Zablit via lldb-commits

https://github.com/charles-zablit updated 
https://github.com/llvm/llvm-project/pull/144731

>From fdff64cca23ab113c80ed431949d7a58bdedb8c7 Mon Sep 17 00:00:00 2001
From: Charles Zablit 
Date: Wed, 18 Jun 2025 16:41:40 +0100
Subject: [PATCH 1/4] [lldb] upgrade HandleFrameFormatVariable callees to
 llvm::Expected

---
 .../Language/CPlusPlus/CPlusPlusLanguage.cpp  | 266 --
 1 file changed, 110 insertions(+), 156 deletions(-)

diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 0f18abb47591d..1810c07652a2b 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -236,199 +236,140 @@ static bool PrettyPrintFunctionNameWithArgs(Stream 
&out_stream,
   return true;
 }
 
-static std::optional
-GetDemangledBasename(const SymbolContext &sc) {
+static llvm::Expected>
+GetAndValidateInfo(const SymbolContext &sc) {
   Mangled mangled = sc.GetPossiblyInlinedFunctionName();
   if (!mangled)
-return std::nullopt;
+return llvm::createStringError("Function does not have a mangled name.");
 
   auto demangled_name = mangled.GetDemangledName().GetStringRef();
   if (demangled_name.empty())
-return std::nullopt;
+return llvm::createStringError("Function does not have a demangled name.");
 
   const std::optional &info = mangled.GetDemangledInfo();
   if (!info)
-return std::nullopt;
+return llvm::createStringError("Function does not have demangled info.");
 
   // Function without a basename is nonsense.
   if (!info->hasBasename())
-return std::nullopt;
+return llvm::createStringError("Info do not have basename range.");
 
-  return demangled_name.slice(info->BasenameRange.first,
-  info->BasenameRange.second);
+  return std::make_pair(demangled_name, *info);
 }
 
-static std::optional
-GetDemangledTemplateArguments(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+static llvm::Expected
+GetDemangledBasename(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  return demangled_name.slice(info.BasenameRange.first,
+  info.BasenameRange.second);
+}
 
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
+static llvm::Expected
+GetDemangledTemplateArguments(const SymbolContext &sc) {
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
+
+  auto [demangled_name, info] = *info_or_err;
 
-  if (info->ArgumentsRange.first < info->BasenameRange.second)
-return std::nullopt;
+  if (info.ArgumentsRange.first < info.BasenameRange.second)
+return llvm::createStringError("Arguments in info are invalid.");
 
-  return demangled_name.slice(info->BasenameRange.second,
-  info->ArgumentsRange.first);
+  return demangled_name.slice(info.BasenameRange.second,
+  info.ArgumentsRange.first);
 }
 
-static std::optional
+static llvm::Expected
 GetDemangledReturnTypeLHS(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::optional &info = mangled.GetDemangledInfo();
-  if (!info)
-return std::nullopt;
+  if (info.ScopeRange.first >= demangled_name.size())
+return llvm::createStringError("Scope range is invalid.");
 
-  // Function without a basename is nonsense.
-  if (!info->hasBasename())
-return std::nullopt;
-
-  if (info->ScopeRange.first >= demangled_name.size())
-return std::nullopt;
-
-  return demangled_name.substr(0, info->ScopeRange.first);
+  return demangled_name.substr(0, info.ScopeRange.first);
 }
 
-static std::optional
+static llvm::Expected
 GetDemangledFunctionQualifiers(const SymbolContext &sc) {
-  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
-  if (!mangled)
-return std::nullopt;
+  auto info_or_err = GetAndValidateInfo(sc);
+  if (!info_or_err)
+return info_or_err.takeError();
 
-  auto demangled_name = mangled.GetDemangledName().GetStringRef();
-  if (demangled_name.empty())
-return std::nullopt;
+  auto [demangled_name, info] = *info_or_err;
 
-  const std::

[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

2025-06-19 Thread Charles Zablit via lldb-commits


@@ -1954,32 +1896,41 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
 FormatEntity::Entry::Type type, Stream &s) {
   switch (type) {
   case FormatEntity::Entry::Type::FunctionScope: {
-std::optional scope = GetDemangledScope(sc);
-if (!scope)
+auto scope_or_err = GetDemangledScope(sc);
+if (!scope_or_err) {
+  LLDB_LOG_ERROR(GetLog(LLDBLog::Language), scope_or_err.takeError(),
+ "Failed to retrieve scope: {0}");
   return false;
+}
 
-s << *scope;
+s << *scope_or_err;
 
 return true;
   }
 
   case FormatEntity::Entry::Type::FunctionBasename: {
-std::optional name = GetDemangledBasename(sc);
-if (!name)
+auto name_or_err = GetDemangledBasename(sc);
+if (!name_or_err) {
+  LLDB_LOG_ERROR(GetLog(LLDBLog::Language), name_or_err.takeError(),
+ "Failed to retrieve basename: {0}");

charles-zablit wrote:

Added better messages for all the `LLDB_LOG_ERROR`.

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


[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

2025-06-19 Thread Charles Zablit via lldb-commits


@@ -236,199 +236,141 @@ static bool PrettyPrintFunctionNameWithArgs(Stream 
&out_stream,
   return true;
 }
 
-static std::optional
-GetDemangledBasename(const SymbolContext &sc) {
+static llvm::Expected>
+GetAndValidateInfo(const SymbolContext &sc) {
   Mangled mangled = sc.GetPossiblyInlinedFunctionName();
   if (!mangled)
-return std::nullopt;
+return llvm::createStringError("Function does not have a mangled name.");
 
   auto demangled_name = mangled.GetDemangledName().GetStringRef();
   if (demangled_name.empty())
-return std::nullopt;
+return llvm::createStringError("Function does not have a demangled name.");

charles-zablit wrote:

Added better messages for all the `createStringError`.

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


[Lldb-commits] [lldb] [lldb][DWARFASTParserClang] GetCXXObjectParameter to take DeclContext DIE parameter (PR #144876)

2025-06-19 Thread Pavel Labath via lldb-commits

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


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


[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

2025-06-19 Thread Charles Zablit via lldb-commits

charles-zablit wrote:

I think we should wait before the following PR gets merged before merging, in 
order to use the new `has` methods.

- https://github.com/llvm/llvm-project/pull/144549

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


[Lldb-commits] [lldb] [lldb][DWARFASTParserClang] Make GetCXXObjectParameter public and call it from unit-tests (PR #144879)

2025-06-19 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Michael Buch (Michael137)


Changes

My goal is to remove the `object_pointer` member on
`ParsedDWARFTypeAttributes` since it's duplicating information that we
retrieve with `GetCXXObjectParameter` anyway. To continue having
coverage for the `DW_AT_object_pointer` code-paths, instead of checking the
`attrs.object_pointer` I'm now calling `GetCXXObjectParameter` directly.
We could find some very roundabout way to go via the Clang AST to check
that the object parameter was parsed correctly, but that quickly became
quite painful.

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

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


3 Files Affected:

- (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
(+10-9) 
- (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h (+4) 
- (modified) lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp 
(+26-12) 


``diff
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 620501b304e63..4f79c8aa3f811 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -163,14 +163,15 @@ static bool TagIsRecordType(dw_tag_t tag) {
 /// 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.
-static DWARFDIE
-GetCXXObjectParameter(const DWARFDIE &subprogram,
-  const clang::DeclContext &containing_decl_ctx) {
+DWARFDIE
+DWARFASTParserClang::GetCXXObjectParameter(const DWARFDIE &subprogram,
+   const DWARFDIE &decl_ctx_die) {
+  assert(subprogram);
   assert(subprogram.Tag() == DW_TAG_subprogram ||
  subprogram.Tag() == DW_TAG_inlined_subroutine ||
  subprogram.Tag() == DW_TAG_subroutine_type);
 
-  if (!DeclKindIsCXXClass(containing_decl_ctx.getDeclKind()))
+  if (!decl_ctx_die.IsStructUnionOrClass())
 return {};
 
   if (DWARFDIE object_parameter =
@@ -1304,8 +1305,7 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
   clang::CallingConv calling_convention =
   ConvertDWARFCallingConventionToClang(attrs);
 
-  const DWARFDIE object_parameter =
-  GetCXXObjectParameter(die, *containing_decl_ctx);
+  const DWARFDIE object_parameter = GetCXXObjectParameter(die, decl_ctx_die);
 
   // clang_type will get the function prototype clang type after this
   // call
@@ -2411,12 +2411,13 @@ 
DWARFASTParserClang::ConstructDemangledNameFromDWARF(const DWARFDIE &die) {
   DWARFDeclContext decl_ctx = die.GetDWARFDeclContext();
   sstr << decl_ctx.GetQualifiedName();
 
+  DWARFDIE decl_ctx_die;
   clang::DeclContext *containing_decl_ctx =
-  GetClangDeclContextContainingDIE(die, nullptr);
+  GetClangDeclContextContainingDIE(die, &decl_ctx_die);
   assert(containing_decl_ctx);
 
-  const unsigned cv_quals = GetCXXMethodCVQuals(
-  die, GetCXXObjectParameter(die, *containing_decl_ctx));
+  const unsigned cv_quals =
+  GetCXXMethodCVQuals(die, GetCXXObjectParameter(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 3994726aa6b3e..111604ce4068a 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -112,6 +112,10 @@ 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);
+
 protected:
   /// Protected typedefs and members.
   /// @{
diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp 
b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
index 6c77736113da3..2d4b79fed4a55 100644
--- a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
+++ b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
@@ -889,18 +889,32 @@ TEST_F(DWARFASTParserClangTests, 
TestParseDWARFAttributes_ObjectPointer) {
   ASSERT_TRUE(context_die.IsValid());
   ASSERT_EQ(context_die.Tag(), DW_TAG_structure_type);
 
-  auto subprogram_definition = context_die.GetSibling();
-  ASSERT_TRUE(subprogram_definition.IsValid());
-  ASSERT_EQ(subprogram_definition.Tag(), DW_TAG_subprogram);
-  ASSERT_FALSE(subprogram_definition.GetAttributeValueAsOpti

[Lldb-commits] [lldb] [lldb][DWARF] Remove object_pointer from ParsedDWARFAttributes (PR #144880)

2025-06-19 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Michael Buch (Michael137)


Changes

We can just always use `GetCXXObjectParameter` instead. We've only used
this attribute to set the object parameter name on ClangASTMetadata,
which doesn't seem like good enough justification to keep it around.

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

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


3 Files Affected:

- (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
(+17-28) 
- (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h (+8-3) 
- (modified) lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp 
(+26-12) 


``diff
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 620501b304e63..d1aef8becfd95 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -163,14 +163,15 @@ static bool TagIsRecordType(dw_tag_t tag) {
 /// 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.
-static DWARFDIE
-GetCXXObjectParameter(const DWARFDIE &subprogram,
-  const clang::DeclContext &containing_decl_ctx) {
+DWARFDIE
+DWARFASTParserClang::GetCXXObjectParameter(const DWARFDIE &subprogram,
+   const DWARFDIE &decl_ctx_die) {
+  assert(subprogram);
   assert(subprogram.Tag() == DW_TAG_subprogram ||
  subprogram.Tag() == DW_TAG_inlined_subroutine ||
  subprogram.Tag() == DW_TAG_subroutine_type);
 
-  if (!DeclKindIsCXXClass(containing_decl_ctx.getDeclKind()))
+  if (!decl_ctx_die.IsStructUnionOrClass())
 return {};
 
   if (DWARFDIE object_parameter =
@@ -444,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;
@@ -1115,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);
@@ -1199,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...
@@ -1224,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));
@@ -1304,8 +1297,7 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
   clang::CallingConv calling_convention =
   ConvertDWARFCallingConventionToClang(attrs);
 
-  const DWARFDIE object_parameter =
-  GetCXXObjectParameter(die, *containing_decl_ctx);
+  const DWARFDIE object_parameter = GetCXXObjectParameter(die, decl_ctx_die);
 
   // clang_type will get the function prototype clang type after this
   // call
@@ -1323,10 +1315,8 @@ 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

[Lldb-commits] [lldb] [lldb][DWARF] Remove object_pointer from ParsedDWARFAttributes (PR #144880)

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

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

We can just always use `GetCXXObjectParameter` instead. We've only used
this attribute to set the object parameter name on ClangASTMetadata,
which doesn't seem like good enough justification to keep it around.

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

>From bda770fa0bd47fc0ac64189f5e25a9b820051d8c Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Thu, 19 Jun 2025 12:11:32 +0100
Subject: [PATCH 1/3] [lldb][DWARFASTParserClang] GetCXXObjectParameter to take
 DeclContext DIE parameter

I'm trying to call `GetCXXObjectParameter` from unit-tests in a
follow-up patch and taking a `DWARFDIE` instead of `clang::DeclContext`
makes that much simpler. These should be equivalent, since all we're
trying to check is that the parent context is a record type.
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp   | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 620501b304e63..7fc1d70898d1d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -163,14 +163,14 @@ static bool TagIsRecordType(dw_tag_t tag) {
 /// 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.
-static DWARFDIE
-GetCXXObjectParameter(const DWARFDIE &subprogram,
-  const clang::DeclContext &containing_decl_ctx) {
+static DWARFDIE GetCXXObjectParameter(const DWARFDIE &subprogram,
+  const DWARFDIE &decl_ctx_die) {
+  assert(subprogram);
   assert(subprogram.Tag() == DW_TAG_subprogram ||
  subprogram.Tag() == DW_TAG_inlined_subroutine ||
  subprogram.Tag() == DW_TAG_subroutine_type);
 
-  if (!DeclKindIsCXXClass(containing_decl_ctx.getDeclKind()))
+  if (!decl_ctx_die.IsStructUnionOrClass())
 return {};
 
   if (DWARFDIE object_parameter =
@@ -1304,8 +1304,7 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
   clang::CallingConv calling_convention =
   ConvertDWARFCallingConventionToClang(attrs);
 
-  const DWARFDIE object_parameter =
-  GetCXXObjectParameter(die, *containing_decl_ctx);
+  const DWARFDIE object_parameter = GetCXXObjectParameter(die, decl_ctx_die);
 
   // clang_type will get the function prototype clang type after this
   // call
@@ -2411,12 +2410,13 @@ 
DWARFASTParserClang::ConstructDemangledNameFromDWARF(const DWARFDIE &die) {
   DWARFDeclContext decl_ctx = die.GetDWARFDeclContext();
   sstr << decl_ctx.GetQualifiedName();
 
+  DWARFDIE decl_ctx_die;
   clang::DeclContext *containing_decl_ctx =
-  GetClangDeclContextContainingDIE(die, nullptr);
+  GetClangDeclContextContainingDIE(die, &decl_ctx_die);
   assert(containing_decl_ctx);
 
-  const unsigned cv_quals = GetCXXMethodCVQuals(
-  die, GetCXXObjectParameter(die, *containing_decl_ctx));
+  const unsigned cv_quals =
+  GetCXXMethodCVQuals(die, GetCXXObjectParameter(die, decl_ctx_die));
 
   ParseChildParameters(containing_decl_ctx, die, is_variadic,
has_template_params, param_types, param_names);

>From de7b06c9afadcf950b96e8a45d7df19dd6a590f9 Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Thu, 19 Jun 2025 12:22:30 +0100
Subject: [PATCH 2/3] [lldb][DWARFASTParserClang] Make GetCXXObjectParameter
 public and call it from unit-tests

My goal is to remove the `object_pointer` member on
`ParsedDWARFTypeAttributes` since it's duplicating information that we
retrieve with `GetCXXObjectParameter` anyway. To continue having
coverage for the `DW_AT_object_pointer` code-paths, instead of checking the
`attrs.object_pointer` I'm now calling `GetCXXObjectParameter` directly.
We could find some very roundabout way to go via the Clang AST to check
that the object parameter was parsed correctly, but that quickly became
quite painful.

Depends on https://github.com/llvm/llvm-project/pull/144876
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  |  5 ++-
 .../SymbolFile/DWARF/DWARFASTParserClang.h|  4 ++
 .../DWARF/DWARFASTParserClangTests.cpp| 38 +--
 3 files changed, 33 insertions(+), 14 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 7fc1d70898d1d..4f79c8aa3f811 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -163,8 +163,9 @@ static bool TagIsRecordType(dw_tag_t tag) {
 /// 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.
-stati

[Lldb-commits] [lldb] [lldb][DWARFASTParserClang] Make GetCXXObjectParameter public and call it from unit-tests (PR #144879)

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

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

My goal is to remove the `object_pointer` member on
`ParsedDWARFTypeAttributes` since it's duplicating information that we
retrieve with `GetCXXObjectParameter` anyway. To continue having
coverage for the `DW_AT_object_pointer` code-paths, instead of checking the
`attrs.object_pointer` I'm now calling `GetCXXObjectParameter` directly.
We could find some very roundabout way to go via the Clang AST to check
that the object parameter was parsed correctly, but that quickly became
quite painful.

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

>From bda770fa0bd47fc0ac64189f5e25a9b820051d8c Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Thu, 19 Jun 2025 12:11:32 +0100
Subject: [PATCH 1/2] [lldb][DWARFASTParserClang] GetCXXObjectParameter to take
 DeclContext DIE parameter

I'm trying to call `GetCXXObjectParameter` from unit-tests in a
follow-up patch and taking a `DWARFDIE` instead of `clang::DeclContext`
makes that much simpler. These should be equivalent, since all we're
trying to check is that the parent context is a record type.
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp   | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 620501b304e63..7fc1d70898d1d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -163,14 +163,14 @@ static bool TagIsRecordType(dw_tag_t tag) {
 /// 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.
-static DWARFDIE
-GetCXXObjectParameter(const DWARFDIE &subprogram,
-  const clang::DeclContext &containing_decl_ctx) {
+static DWARFDIE GetCXXObjectParameter(const DWARFDIE &subprogram,
+  const DWARFDIE &decl_ctx_die) {
+  assert(subprogram);
   assert(subprogram.Tag() == DW_TAG_subprogram ||
  subprogram.Tag() == DW_TAG_inlined_subroutine ||
  subprogram.Tag() == DW_TAG_subroutine_type);
 
-  if (!DeclKindIsCXXClass(containing_decl_ctx.getDeclKind()))
+  if (!decl_ctx_die.IsStructUnionOrClass())
 return {};
 
   if (DWARFDIE object_parameter =
@@ -1304,8 +1304,7 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
   clang::CallingConv calling_convention =
   ConvertDWARFCallingConventionToClang(attrs);
 
-  const DWARFDIE object_parameter =
-  GetCXXObjectParameter(die, *containing_decl_ctx);
+  const DWARFDIE object_parameter = GetCXXObjectParameter(die, decl_ctx_die);
 
   // clang_type will get the function prototype clang type after this
   // call
@@ -2411,12 +2410,13 @@ 
DWARFASTParserClang::ConstructDemangledNameFromDWARF(const DWARFDIE &die) {
   DWARFDeclContext decl_ctx = die.GetDWARFDeclContext();
   sstr << decl_ctx.GetQualifiedName();
 
+  DWARFDIE decl_ctx_die;
   clang::DeclContext *containing_decl_ctx =
-  GetClangDeclContextContainingDIE(die, nullptr);
+  GetClangDeclContextContainingDIE(die, &decl_ctx_die);
   assert(containing_decl_ctx);
 
-  const unsigned cv_quals = GetCXXMethodCVQuals(
-  die, GetCXXObjectParameter(die, *containing_decl_ctx));
+  const unsigned cv_quals =
+  GetCXXMethodCVQuals(die, GetCXXObjectParameter(die, decl_ctx_die));
 
   ParseChildParameters(containing_decl_ctx, die, is_variadic,
has_template_params, param_types, param_names);

>From de7b06c9afadcf950b96e8a45d7df19dd6a590f9 Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Thu, 19 Jun 2025 12:22:30 +0100
Subject: [PATCH 2/2] [lldb][DWARFASTParserClang] Make GetCXXObjectParameter
 public and call it from unit-tests

My goal is to remove the `object_pointer` member on
`ParsedDWARFTypeAttributes` since it's duplicating information that we
retrieve with `GetCXXObjectParameter` anyway. To continue having
coverage for the `DW_AT_object_pointer` code-paths, instead of checking the
`attrs.object_pointer` I'm now calling `GetCXXObjectParameter` directly.
We could find some very roundabout way to go via the Clang AST to check
that the object parameter was parsed correctly, but that quickly became
quite painful.

Depends on https://github.com/llvm/llvm-project/pull/144876
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  |  5 ++-
 .../SymbolFile/DWARF/DWARFASTParserClang.h|  4 ++
 .../DWARF/DWARFASTParserClangTests.cpp| 38 +--
 3 files changed, 33 insertions(+), 14 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 7fc1d70898d1d..4f79c8aa3f811 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolF

[Lldb-commits] [lldb] [lldb][DWARF] Remove object_pointer from ParsedDWARFAttributes (PR #144880)

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

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

>From bda770fa0bd47fc0ac64189f5e25a9b820051d8c Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Thu, 19 Jun 2025 12:11:32 +0100
Subject: [PATCH 1/5] [lldb][DWARFASTParserClang] GetCXXObjectParameter to take
 DeclContext DIE parameter

I'm trying to call `GetCXXObjectParameter` from unit-tests in a
follow-up patch and taking a `DWARFDIE` instead of `clang::DeclContext`
makes that much simpler. These should be equivalent, since all we're
trying to check is that the parent context is a record type.
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp   | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 620501b304e63..7fc1d70898d1d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -163,14 +163,14 @@ static bool TagIsRecordType(dw_tag_t tag) {
 /// 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.
-static DWARFDIE
-GetCXXObjectParameter(const DWARFDIE &subprogram,
-  const clang::DeclContext &containing_decl_ctx) {
+static DWARFDIE GetCXXObjectParameter(const DWARFDIE &subprogram,
+  const DWARFDIE &decl_ctx_die) {
+  assert(subprogram);
   assert(subprogram.Tag() == DW_TAG_subprogram ||
  subprogram.Tag() == DW_TAG_inlined_subroutine ||
  subprogram.Tag() == DW_TAG_subroutine_type);
 
-  if (!DeclKindIsCXXClass(containing_decl_ctx.getDeclKind()))
+  if (!decl_ctx_die.IsStructUnionOrClass())
 return {};
 
   if (DWARFDIE object_parameter =
@@ -1304,8 +1304,7 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
   clang::CallingConv calling_convention =
   ConvertDWARFCallingConventionToClang(attrs);
 
-  const DWARFDIE object_parameter =
-  GetCXXObjectParameter(die, *containing_decl_ctx);
+  const DWARFDIE object_parameter = GetCXXObjectParameter(die, decl_ctx_die);
 
   // clang_type will get the function prototype clang type after this
   // call
@@ -2411,12 +2410,13 @@ 
DWARFASTParserClang::ConstructDemangledNameFromDWARF(const DWARFDIE &die) {
   DWARFDeclContext decl_ctx = die.GetDWARFDeclContext();
   sstr << decl_ctx.GetQualifiedName();
 
+  DWARFDIE decl_ctx_die;
   clang::DeclContext *containing_decl_ctx =
-  GetClangDeclContextContainingDIE(die, nullptr);
+  GetClangDeclContextContainingDIE(die, &decl_ctx_die);
   assert(containing_decl_ctx);
 
-  const unsigned cv_quals = GetCXXMethodCVQuals(
-  die, GetCXXObjectParameter(die, *containing_decl_ctx));
+  const unsigned cv_quals =
+  GetCXXMethodCVQuals(die, GetCXXObjectParameter(die, decl_ctx_die));
 
   ParseChildParameters(containing_decl_ctx, die, is_variadic,
has_template_params, param_types, param_names);

>From de7b06c9afadcf950b96e8a45d7df19dd6a590f9 Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Thu, 19 Jun 2025 12:22:30 +0100
Subject: [PATCH 2/5] [lldb][DWARFASTParserClang] Make GetCXXObjectParameter
 public and call it from unit-tests

My goal is to remove the `object_pointer` member on
`ParsedDWARFTypeAttributes` since it's duplicating information that we
retrieve with `GetCXXObjectParameter` anyway. To continue having
coverage for the `DW_AT_object_pointer` code-paths, instead of checking the
`attrs.object_pointer` I'm now calling `GetCXXObjectParameter` directly.
We could find some very roundabout way to go via the Clang AST to check
that the object parameter was parsed correctly, but that quickly became
quite painful.

Depends on https://github.com/llvm/llvm-project/pull/144876
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  |  5 ++-
 .../SymbolFile/DWARF/DWARFASTParserClang.h|  4 ++
 .../DWARF/DWARFASTParserClangTests.cpp| 38 +--
 3 files changed, 33 insertions(+), 14 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 7fc1d70898d1d..4f79c8aa3f811 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -163,8 +163,9 @@ static bool TagIsRecordType(dw_tag_t tag) {
 /// 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.
-static DWARFDIE GetCXXObjectParameter(const DWARFDIE &subprogram,
-  const DWARFDIE &decl_ctx_die) {
+DWARFDIE
+DWARFASTParserClang::GetCXXObjectParameter(const DWARFDIE &subprogram,
+   const DWARFDIE

[Lldb-commits] [lldb] 30824c4 - [lldb][DWARFASTParserClang] GetCXXObjectParameter to take DeclContext DIE parameter (#144876)

2025-06-19 Thread via lldb-commits

Author: Michael Buch
Date: 2025-06-19T12:48:39+01:00
New Revision: 30824c449a893771c3f25f0eb29cfa9d2cfd4f15

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

LOG: [lldb][DWARFASTParserClang] GetCXXObjectParameter to take DeclContext DIE 
parameter (#144876)

I'm trying to call `GetCXXObjectParameter` from unit-tests in a
follow-up patch and taking a `DWARFDIE` instead of `clang::DeclContext`
makes that much simpler. These should be equivalent, since all we're
trying to check is that the parent context is a record type.

Added: 


Modified: 
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp

Removed: 




diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 620501b304e63..7fc1d70898d1d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -163,14 +163,14 @@ static bool TagIsRecordType(dw_tag_t tag) {
 /// 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.
-static DWARFDIE
-GetCXXObjectParameter(const DWARFDIE &subprogram,
-  const clang::DeclContext &containing_decl_ctx) {
+static DWARFDIE GetCXXObjectParameter(const DWARFDIE &subprogram,
+  const DWARFDIE &decl_ctx_die) {
+  assert(subprogram);
   assert(subprogram.Tag() == DW_TAG_subprogram ||
  subprogram.Tag() == DW_TAG_inlined_subroutine ||
  subprogram.Tag() == DW_TAG_subroutine_type);
 
-  if (!DeclKindIsCXXClass(containing_decl_ctx.getDeclKind()))
+  if (!decl_ctx_die.IsStructUnionOrClass())
 return {};
 
   if (DWARFDIE object_parameter =
@@ -1304,8 +1304,7 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
   clang::CallingConv calling_convention =
   ConvertDWARFCallingConventionToClang(attrs);
 
-  const DWARFDIE object_parameter =
-  GetCXXObjectParameter(die, *containing_decl_ctx);
+  const DWARFDIE object_parameter = GetCXXObjectParameter(die, decl_ctx_die);
 
   // clang_type will get the function prototype clang type after this
   // call
@@ -2411,12 +2410,13 @@ 
DWARFASTParserClang::ConstructDemangledNameFromDWARF(const DWARFDIE &die) {
   DWARFDeclContext decl_ctx = die.GetDWARFDeclContext();
   sstr << decl_ctx.GetQualifiedName();
 
+  DWARFDIE decl_ctx_die;
   clang::DeclContext *containing_decl_ctx =
-  GetClangDeclContextContainingDIE(die, nullptr);
+  GetClangDeclContextContainingDIE(die, &decl_ctx_die);
   assert(containing_decl_ctx);
 
-  const unsigned cv_quals = GetCXXMethodCVQuals(
-  die, GetCXXObjectParameter(die, *containing_decl_ctx));
+  const unsigned cv_quals =
+  GetCXXMethodCVQuals(die, GetCXXObjectParameter(die, decl_ctx_die));
 
   ParseChildParameters(containing_decl_ctx, die, is_variadic,
has_template_params, param_types, param_names);



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


[Lldb-commits] [lldb] [lldb][darwin] force BuiltinHeadersInSystemModules to be always false (PR #144913)

2025-06-19 Thread Charles Zablit via lldb-commits

https://github.com/charles-zablit created 
https://github.com/llvm/llvm-project/pull/144913

`SDKSupportsBuiltinModules` always returns true on newer versions of Darwin 
based OS. The only way for this call to return `false` would be to have a 
version mismatch between lldb and the SDK (recent lldb manually installed on 
macOS 14 for instance).

This patch removes this check and hardcodes the value of 
`BuiltinHeadersInSystemModules` to `false`.

>From e28a9e6249077c9ffca878cbf4c933b6f4f9eab8 Mon Sep 17 00:00:00 2001
From: Charles Zablit 
Date: Thu, 19 Jun 2025 16:17:33 +0100
Subject: [PATCH] [lldb][darwin] force BuiltinHeadersInSystemModules to be
 always false

---
 lldb/include/lldb/Utility/XcodeSDK.h  | 13 -
 .../Clang/ClangExpressionParser.cpp   | 50 +--
 lldb/source/Utility/XcodeSDK.cpp  | 21 
 3 files changed, 1 insertion(+), 83 deletions(-)

diff --git a/lldb/include/lldb/Utility/XcodeSDK.h 
b/lldb/include/lldb/Utility/XcodeSDK.h
index ceb8abb8c502d..a1a0ec415b90e 100644
--- a/lldb/include/lldb/Utility/XcodeSDK.h
+++ b/lldb/include/lldb/Utility/XcodeSDK.h
@@ -93,19 +93,6 @@ class XcodeSDK {
   static bool SDKSupportsModules(Type type, llvm::VersionTuple version);
   static bool SDKSupportsModules(Type desired_type, const FileSpec &sdk_path);
 
-  /// Returns true if the SDK for the specified triple supports
-  /// builtin modules in system headers.
-  ///
-  /// NOTE: should be kept in sync with sdkSupportsBuiltinModules in
-  /// Toolchains/Darwin.cpp
-  ///
-  /// FIXME: this function will be removed once LLDB's ClangExpressionParser
-  /// constructs the compiler instance through the driver/toolchain. See \ref
-  /// SetupImportStdModuleLangOpts
-  ///
-  static bool SDKSupportsBuiltinModules(const llvm::Triple &target_triple,
-llvm::VersionTuple sdk_version);
-
   /// Return the canonical SDK name, such as "macosx" for the macOS SDK.
   static std::string GetCanonicalName(Info info);
   /// Return the best-matching SDK type for a specific triple.
diff --git 
a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp 
b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 7aa9cae5a5614..3caf30c5822a2 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -319,49 +319,6 @@ class ClangDiagnosticManagerAdapter : public 
clang::DiagnosticConsumer {
   StringRef m_filename;
 };
 
-/// Returns true if the SDK for the specified triple supports
-/// builtin modules in system headers. This is used to decide
-/// whether to pass -fbuiltin-headers-in-system-modules to
-/// the compiler instance when compiling the `std` module.
-static llvm::Expected
-sdkSupportsBuiltinModules(lldb_private::Target &target) {
-  auto arch_spec = target.GetArchitecture();
-  auto const &triple = arch_spec.GetTriple();
-  auto module_sp = target.GetExecutableModule();
-  if (!module_sp)
-return llvm::createStringError("Executable module not found.");
-
-  // Get SDK path that the target was compiled against.
-  auto platform_sp = target.GetPlatform();
-  if (!platform_sp)
-return llvm::createStringError("No Platform plugin found on target.");
-
-  auto sdk_or_err = platform_sp->GetSDKPathFromDebugInfo(*module_sp);
-  if (!sdk_or_err)
-return sdk_or_err.takeError();
-
-  // Use the SDK path from debug-info to find a local matching SDK directory.
-  auto sdk_path_or_err =
-  HostInfo::GetSDKRoot(HostInfo::SDKOptions{std::move(sdk_or_err->first)});
-  if (!sdk_path_or_err)
-return sdk_path_or_err.takeError();
-
-  auto VFS = FileSystem::Instance().GetVirtualFileSystem();
-  if (!VFS)
-return llvm::createStringError("No virtual filesystem available.");
-
-  // Extract SDK version from the /path/to/some.sdk/SDKSettings.json
-  auto parsed_or_err = clang::parseDarwinSDKInfo(*VFS, *sdk_path_or_err);
-  if (!parsed_or_err)
-return parsed_or_err.takeError();
-
-  auto maybe_sdk = *parsed_or_err;
-  if (!maybe_sdk)
-return llvm::createStringError("Couldn't find Darwin SDK info.");
-
-  return XcodeSDK::SDKSupportsBuiltinModules(triple, maybe_sdk->getVersion());
-}
-
 static void SetupModuleHeaderPaths(CompilerInstance *compiler,
std::vector 
include_directories,
lldb::TargetSP target_sp) {
@@ -723,12 +680,7 @@ static void SetupImportStdModuleLangOpts(CompilerInstance 
&compiler,
   lang_opts.GNUKeywords = true;
   lang_opts.CPlusPlus11 = true;
 
-  if (auto supported_or_err = sdkSupportsBuiltinModules(target))
-lang_opts.BuiltinHeadersInSystemModules = !*supported_or_err;
-  else
-LLDB_LOG_ERROR(log, supported_or_err.takeError(),
-   "Failed to determine BuiltinHeadersInSystemModules when "
-   "setting up import-std-module: {0}");
+  lang_opts.BuiltinHeadersInSys

[Lldb-commits] [lldb] [lldb][darwin] force BuiltinHeadersInSystemModules to be always false (PR #144913)

2025-06-19 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Charles Zablit (charles-zablit)


Changes

`SDKSupportsBuiltinModules` always returns true on newer versions of Darwin 
based OS. The only way for this call to return `false` would be to have a 
version mismatch between lldb and the SDK (recent lldb manually installed on 
macOS 14 for instance).

This patch removes this check and hardcodes the value of 
`BuiltinHeadersInSystemModules` to `false`.

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


3 Files Affected:

- (modified) lldb/include/lldb/Utility/XcodeSDK.h (-13) 
- (modified) 
lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp (+1-49) 
- (modified) lldb/source/Utility/XcodeSDK.cpp (-21) 


``diff
diff --git a/lldb/include/lldb/Utility/XcodeSDK.h 
b/lldb/include/lldb/Utility/XcodeSDK.h
index ceb8abb8c502d..a1a0ec415b90e 100644
--- a/lldb/include/lldb/Utility/XcodeSDK.h
+++ b/lldb/include/lldb/Utility/XcodeSDK.h
@@ -93,19 +93,6 @@ class XcodeSDK {
   static bool SDKSupportsModules(Type type, llvm::VersionTuple version);
   static bool SDKSupportsModules(Type desired_type, const FileSpec &sdk_path);
 
-  /// Returns true if the SDK for the specified triple supports
-  /// builtin modules in system headers.
-  ///
-  /// NOTE: should be kept in sync with sdkSupportsBuiltinModules in
-  /// Toolchains/Darwin.cpp
-  ///
-  /// FIXME: this function will be removed once LLDB's ClangExpressionParser
-  /// constructs the compiler instance through the driver/toolchain. See \ref
-  /// SetupImportStdModuleLangOpts
-  ///
-  static bool SDKSupportsBuiltinModules(const llvm::Triple &target_triple,
-llvm::VersionTuple sdk_version);
-
   /// Return the canonical SDK name, such as "macosx" for the macOS SDK.
   static std::string GetCanonicalName(Info info);
   /// Return the best-matching SDK type for a specific triple.
diff --git 
a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp 
b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 7aa9cae5a5614..3caf30c5822a2 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -319,49 +319,6 @@ class ClangDiagnosticManagerAdapter : public 
clang::DiagnosticConsumer {
   StringRef m_filename;
 };
 
-/// Returns true if the SDK for the specified triple supports
-/// builtin modules in system headers. This is used to decide
-/// whether to pass -fbuiltin-headers-in-system-modules to
-/// the compiler instance when compiling the `std` module.
-static llvm::Expected
-sdkSupportsBuiltinModules(lldb_private::Target &target) {
-  auto arch_spec = target.GetArchitecture();
-  auto const &triple = arch_spec.GetTriple();
-  auto module_sp = target.GetExecutableModule();
-  if (!module_sp)
-return llvm::createStringError("Executable module not found.");
-
-  // Get SDK path that the target was compiled against.
-  auto platform_sp = target.GetPlatform();
-  if (!platform_sp)
-return llvm::createStringError("No Platform plugin found on target.");
-
-  auto sdk_or_err = platform_sp->GetSDKPathFromDebugInfo(*module_sp);
-  if (!sdk_or_err)
-return sdk_or_err.takeError();
-
-  // Use the SDK path from debug-info to find a local matching SDK directory.
-  auto sdk_path_or_err =
-  HostInfo::GetSDKRoot(HostInfo::SDKOptions{std::move(sdk_or_err->first)});
-  if (!sdk_path_or_err)
-return sdk_path_or_err.takeError();
-
-  auto VFS = FileSystem::Instance().GetVirtualFileSystem();
-  if (!VFS)
-return llvm::createStringError("No virtual filesystem available.");
-
-  // Extract SDK version from the /path/to/some.sdk/SDKSettings.json
-  auto parsed_or_err = clang::parseDarwinSDKInfo(*VFS, *sdk_path_or_err);
-  if (!parsed_or_err)
-return parsed_or_err.takeError();
-
-  auto maybe_sdk = *parsed_or_err;
-  if (!maybe_sdk)
-return llvm::createStringError("Couldn't find Darwin SDK info.");
-
-  return XcodeSDK::SDKSupportsBuiltinModules(triple, maybe_sdk->getVersion());
-}
-
 static void SetupModuleHeaderPaths(CompilerInstance *compiler,
std::vector 
include_directories,
lldb::TargetSP target_sp) {
@@ -723,12 +680,7 @@ static void SetupImportStdModuleLangOpts(CompilerInstance 
&compiler,
   lang_opts.GNUKeywords = true;
   lang_opts.CPlusPlus11 = true;
 
-  if (auto supported_or_err = sdkSupportsBuiltinModules(target))
-lang_opts.BuiltinHeadersInSystemModules = !*supported_or_err;
-  else
-LLDB_LOG_ERROR(log, supported_or_err.takeError(),
-   "Failed to determine BuiltinHeadersInSystemModules when "
-   "setting up import-std-module: {0}");
+  lang_opts.BuiltinHeadersInSystemModules = false;
 
   // The Darwin libc expects this macro to be set.
   lang_opts.GNUCVersion = 40201;
diff --git a/lldb/source/Utility/XcodeSDK.cpp 

[Lldb-commits] [lldb] [lldb] upgrade HandleFrameFormatVariable callees to llvm::Expected (PR #144731)

2025-06-19 Thread Charles Zablit via lldb-commits

charles-zablit wrote:

> I think we should wait before the following PR gets merged before merging, in 
> order to use the new `has` methods.

Done ✅ 


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


[Lldb-commits] [lldb] [LLDB] Add type summaries for MSVC STL strings (PR #143177)

2025-06-19 Thread via lldb-commits

https://github.com/Nerixyz updated 
https://github.com/llvm/llvm-project/pull/143177

>From 9df39618354ed3b9469249440c103a81293bbb97 Mon Sep 17 00:00:00 2001
From: Nerixyz 
Date: Wed, 18 Jun 2025 21:49:16 +0200
Subject: [PATCH] [LLDB] Add type summaries for MSVC STL strings

---
 .../lldb/DataFormatters/StringPrinter.h   |  15 ++
 .../Python/lldbsuite/test/configuration.py|   2 +
 lldb/packages/Python/lldbsuite/test/dotest.py |  23 +++
 .../Python/lldbsuite/test/dotest_args.py  |   6 +
 .../Python/lldbsuite/test/test_categories.py  |   1 +
 .../Plugins/Language/CPlusPlus/CMakeLists.txt |   1 +
 .../Language/CPlusPlus/CPlusPlusLanguage.cpp  | 138 +
 .../Plugins/Language/CPlusPlus/LibStdcpp.cpp  | 142 -
 .../Plugins/Language/CPlusPlus/LibStdcpp.h|   4 +-
 .../Plugins/Language/CPlusPlus/MsvcStl.cpp| 146 ++
 .../Plugins/Language/CPlusPlus/MsvcStl.h  |  35 +
 .../msvcstl/string/Makefile   |   4 +
 .../string/TestDataFormatterStdString.py  | 118 ++
 .../msvcstl/string/main.cpp   |  40 +
 .../msvcstl/u8string/Makefile |   4 +
 .../u8string/TestDataFormatterStdU8String.py  |  31 
 .../msvcstl/u8string/main.cpp |  14 ++
 lldb/test/API/lit.cfg.py  |   3 +
 18 files changed, 582 insertions(+), 145 deletions(-)
 create mode 100644 lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp
 create mode 100644 lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
 create mode 100644 
lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvcstl/string/Makefile
 create mode 100644 
lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvcstl/string/TestDataFormatterStdString.py
 create mode 100644 
lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvcstl/string/main.cpp
 create mode 100644 
lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvcstl/u8string/Makefile
 create mode 100644 
lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvcstl/u8string/TestDataFormatterStdU8String.py
 create mode 100644 
lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvcstl/u8string/main.cpp

diff --git a/lldb/include/lldb/DataFormatters/StringPrinter.h 
b/lldb/include/lldb/DataFormatters/StringPrinter.h
index 4169f53e63f38..4ebe712be60e1 100644
--- a/lldb/include/lldb/DataFormatters/StringPrinter.h
+++ b/lldb/include/lldb/DataFormatters/StringPrinter.h
@@ -152,6 +152,21 @@ class StringPrinter {
   template 
   static bool
   ReadBufferAndDumpToStream(const ReadBufferAndDumpToStreamOptions &options);
+
+  template 
+  static constexpr uint64_t ElementByteSize() {
+switch (element_type) {
+case StringElementType::ASCII:
+case StringElementType::UTF8:
+  return 1;
+case StringElementType::UTF16:
+  return 2;
+case StringElementType::UTF32:
+  return 3;
+default:
+  return 0;
+}
+  }
 };
 
 } // namespace formatters
diff --git a/lldb/packages/Python/lldbsuite/test/configuration.py 
b/lldb/packages/Python/lldbsuite/test/configuration.py
index b2d91fd211477..4ec892bef69f9 100644
--- a/lldb/packages/Python/lldbsuite/test/configuration.py
+++ b/lldb/packages/Python/lldbsuite/test/configuration.py
@@ -134,6 +134,8 @@
 libcxx_include_target_dir = None
 libcxx_library_dir = None
 
+target_triple = None
+
 # A plugin whose tests will be enabled, like intel-pt.
 enabled_plugins = []
 
diff --git a/lldb/packages/Python/lldbsuite/test/dotest.py 
b/lldb/packages/Python/lldbsuite/test/dotest.py
index d7f274ac4f60e..dd6fbdf8daed4 100644
--- a/lldb/packages/Python/lldbsuite/test/dotest.py
+++ b/lldb/packages/Python/lldbsuite/test/dotest.py
@@ -299,6 +299,8 @@ def parseOptionsAndInitTestdirs():
 configuration.libcxx_library_dir = args.libcxx_library_dir
 configuration.cmake_build_type = args.cmake_build_type.lower()
 
+configuration.target_triple = args.target_triple
+
 if args.channels:
 lldbtest_config.channels = args.channels
 
@@ -831,6 +833,26 @@ def checkLibstdcxxSupport():
 configuration.skip_categories.append("libstdcxx")
 
 
+def canRunMsvcStlTests():
+if "windows-msvc" in configuration.target_triple:
+return True, "MSVC STL is present on *windows-msvc*"
+return (
+False,
+f"Don't know how to build with MSVC's STL on 
{configuration.target_triple}",
+)
+
+
+def checkMsvcStlSupport():
+result, reason = canRunMsvcStlTests()
+if result:
+return  # msvcstl supported
+if "msvcstl" in configuration.categories_list:
+return  # msvcstl category explicitly requested, let it run.
+if configuration.verbose:
+print(f"msvcstl tests will not be run because: {reason}")
+configuration.skip_categories.append("msvcstl")
+
+
 def canRunWatchpointTests():
 from lldbsuite.test import lldbplatformutil
 
@@ -1044,6 +1066,7 @@ def run_suite():
 
 checkLibcxxSupport(

[Lldb-commits] [lldb] [lldb] Add DWARFExpressionEntry and GetExpressionEntryAtAddress() to … (PR #144238)

2025-06-19 Thread Abdullah Mohammad Amin via lldb-commits


@@ -59,6 +59,18 @@ class DWARFExpressionList {
 
   lldb::addr_t GetFuncFileAddress() { return m_func_file_addr; }
 
+  /// Represents an entry in the DWARFExpressionList with all needed metadata
+  struct DWARFExpressionEntry {
+lldb::addr_t base;
+lldb::addr_t end;

UltimateForce21 wrote:

These are file addresses (without offsets applied), I will try to make that 
more clear both in the comments and in the variable names. I'll also take a 
look into the AddressRange class and see if I can utilize it, thank you for the 
pointers.


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


[Lldb-commits] [lldb] [lldb] Add DWARFExpressionEntry and GetExpressionEntryAtAddress() to … (PR #144238)

2025-06-19 Thread Abdullah Mohammad Amin via lldb-commits


@@ -53,6 +53,27 @@ bool DWARFExpressionList::ContainsAddress(lldb::addr_t 
func_load_addr,
   return GetExpressionAtAddress(func_load_addr, addr) != nullptr;
 }
 
+llvm::Expected
+DWARFExpressionList::GetExpressionEntryAtAddress(lldb::addr_t func_load_addr,
+ lldb::addr_t load_addr) const 
{
+  if (const DWARFExpression *expr = GetAlwaysValidExpr()) {
+return DWARFExpressionEntry{0, LLDB_INVALID_ADDRESS, expr};
+  }
+
+  if (func_load_addr == LLDB_INVALID_ADDRESS)
+func_load_addr = m_func_file_addr;
+
+  addr_t addr = load_addr - func_load_addr + m_func_file_addr;
+  uint32_t index = m_exprs.FindEntryIndexThatContains(addr);
+  if (index == UINT32_MAX) {
+return llvm::createStringError(llvm::inconvertibleErrorCode(),
+   "No DWARF expression found for address 
0x%llx", addr);

UltimateForce21 wrote:

Sounds good, I will refactor it to return std::optional instead.

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


[Lldb-commits] [lldb] [lldb-dap] Make connection URLs match lldb (PR #144770)

2025-06-19 Thread Pavel Labath via lldb-commits

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

Thanks.

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


[Lldb-commits] [lldb] [lldb][DWARFASTParserClang] GetCXXObjectParameter to take DeclContext DIE parameter (PR #144876)

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

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

I'm trying to call `GetCXXObjectParameter` from unit-tests in a follow-up patch 
and taking a `DWARFDIE` instead of `clang::DeclContext` makes that much 
simpler. These should be equivalent, since all we're trying to check is that 
the parent context is a record type.

>From bda770fa0bd47fc0ac64189f5e25a9b820051d8c Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Thu, 19 Jun 2025 12:11:32 +0100
Subject: [PATCH] [lldb][DWARFASTParserClang] GetCXXObjectParameter to take
 DeclContext DIE parameter

I'm trying to call `GetCXXObjectParameter` from unit-tests in a
follow-up patch and taking a `DWARFDIE` instead of `clang::DeclContext`
makes that much simpler. These should be equivalent, since all we're
trying to check is that the parent context is a record type.
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp   | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 620501b304e63..7fc1d70898d1d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -163,14 +163,14 @@ static bool TagIsRecordType(dw_tag_t tag) {
 /// 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.
-static DWARFDIE
-GetCXXObjectParameter(const DWARFDIE &subprogram,
-  const clang::DeclContext &containing_decl_ctx) {
+static DWARFDIE GetCXXObjectParameter(const DWARFDIE &subprogram,
+  const DWARFDIE &decl_ctx_die) {
+  assert(subprogram);
   assert(subprogram.Tag() == DW_TAG_subprogram ||
  subprogram.Tag() == DW_TAG_inlined_subroutine ||
  subprogram.Tag() == DW_TAG_subroutine_type);
 
-  if (!DeclKindIsCXXClass(containing_decl_ctx.getDeclKind()))
+  if (!decl_ctx_die.IsStructUnionOrClass())
 return {};
 
   if (DWARFDIE object_parameter =
@@ -1304,8 +1304,7 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
   clang::CallingConv calling_convention =
   ConvertDWARFCallingConventionToClang(attrs);
 
-  const DWARFDIE object_parameter =
-  GetCXXObjectParameter(die, *containing_decl_ctx);
+  const DWARFDIE object_parameter = GetCXXObjectParameter(die, decl_ctx_die);
 
   // clang_type will get the function prototype clang type after this
   // call
@@ -2411,12 +2410,13 @@ 
DWARFASTParserClang::ConstructDemangledNameFromDWARF(const DWARFDIE &die) {
   DWARFDeclContext decl_ctx = die.GetDWARFDeclContext();
   sstr << decl_ctx.GetQualifiedName();
 
+  DWARFDIE decl_ctx_die;
   clang::DeclContext *containing_decl_ctx =
-  GetClangDeclContextContainingDIE(die, nullptr);
+  GetClangDeclContextContainingDIE(die, &decl_ctx_die);
   assert(containing_decl_ctx);
 
-  const unsigned cv_quals = GetCXXMethodCVQuals(
-  die, GetCXXObjectParameter(die, *containing_decl_ctx));
+  const unsigned cv_quals =
+  GetCXXMethodCVQuals(die, GetCXXObjectParameter(die, decl_ctx_die));
 
   ParseChildParameters(containing_decl_ctx, die, is_variadic,
has_template_params, param_types, param_names);

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


[Lldb-commits] [lldb] [lldb][DWARFASTParserClang] GetCXXObjectParameter to take DeclContext DIE parameter (PR #144876)

2025-06-19 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Michael Buch (Michael137)


Changes

I'm trying to call `GetCXXObjectParameter` from unit-tests in a follow-up patch 
and taking a `DWARFDIE` instead of `clang::DeclContext` makes that much 
simpler. These should be equivalent, since all we're trying to check is that 
the parent context is a record type.

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


1 Files Affected:

- (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
(+9-9) 


``diff
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 620501b304e63..7fc1d70898d1d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -163,14 +163,14 @@ static bool TagIsRecordType(dw_tag_t tag) {
 /// 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.
-static DWARFDIE
-GetCXXObjectParameter(const DWARFDIE &subprogram,
-  const clang::DeclContext &containing_decl_ctx) {
+static DWARFDIE GetCXXObjectParameter(const DWARFDIE &subprogram,
+  const DWARFDIE &decl_ctx_die) {
+  assert(subprogram);
   assert(subprogram.Tag() == DW_TAG_subprogram ||
  subprogram.Tag() == DW_TAG_inlined_subroutine ||
  subprogram.Tag() == DW_TAG_subroutine_type);
 
-  if (!DeclKindIsCXXClass(containing_decl_ctx.getDeclKind()))
+  if (!decl_ctx_die.IsStructUnionOrClass())
 return {};
 
   if (DWARFDIE object_parameter =
@@ -1304,8 +1304,7 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
   clang::CallingConv calling_convention =
   ConvertDWARFCallingConventionToClang(attrs);
 
-  const DWARFDIE object_parameter =
-  GetCXXObjectParameter(die, *containing_decl_ctx);
+  const DWARFDIE object_parameter = GetCXXObjectParameter(die, decl_ctx_die);
 
   // clang_type will get the function prototype clang type after this
   // call
@@ -2411,12 +2410,13 @@ 
DWARFASTParserClang::ConstructDemangledNameFromDWARF(const DWARFDIE &die) {
   DWARFDeclContext decl_ctx = die.GetDWARFDeclContext();
   sstr << decl_ctx.GetQualifiedName();
 
+  DWARFDIE decl_ctx_die;
   clang::DeclContext *containing_decl_ctx =
-  GetClangDeclContextContainingDIE(die, nullptr);
+  GetClangDeclContextContainingDIE(die, &decl_ctx_die);
   assert(containing_decl_ctx);
 
-  const unsigned cv_quals = GetCXXMethodCVQuals(
-  die, GetCXXObjectParameter(die, *containing_decl_ctx));
+  const unsigned cv_quals =
+  GetCXXMethodCVQuals(die, GetCXXObjectParameter(die, decl_ctx_die));
 
   ParseChildParameters(containing_decl_ctx, die, is_variadic,
has_template_params, param_types, param_names);

``




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


[Lldb-commits] [lldb] [lldb][test] Synchronize `__compressed_pair_padding` with libc++ (PR #142516)

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

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

Thanks for adjusting! I know it's quite gnarly with all these ifdefs

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


[Lldb-commits] [lldb] [lldb][AArch64] Correctly invalidate svg when vg is written (PR #140875)

2025-06-19 Thread David Spickett via lldb-commits

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


[Lldb-commits] [lldb] 6273c5d - [lldb][AArch64] Correctly invalidate svg when vg is written (#140875)

2025-06-19 Thread via lldb-commits

Author: David Spickett
Date: 2025-06-19T09:57:07+01:00
New Revision: 6273c5d4d3540204cb0d298cf1cf74ba94ed2a6c

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

LOG: [lldb][AArch64] Correctly invalidate svg when vg is written (#140875)

Recently the Linux Kernel has fixed a bunch of issues in SME support and
while testing that, I found two tests failing:
FAIL: test_za_register_dynamic_config_main_disabled
(TestZAThreadedDynamic.AArch64ZAThreadedTestCase)
FAIL: test_za_register_dynamic_config_main_enabled
(TestZAThreadedDynamic.AArch64ZAThreadedTestCase)

These tests write to vg during streaming mode from lldb and expect to
see that za has been resized to match it. Instead, it was unavailable.
lldb-server was sending the correct amount of data but lldb client was
expecting the old size.

Turns out that instead of a write to vg invalidating svg, it was
invalidating... something else. I'm still not sure how these tests ever
worked but with this one line fix, they pass again.

I did not see this issue with SVE or streaming SVE Z registers because
those always resize using the value of vg, and vg always has the value
we just wrote.

(remember that vg is the vector length of the **current** mode, not of
non-streaming mode, whereas svg is the vector length of streaming mode,
even if you are currently in non-streaming mode)

Added: 


Modified: 
lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp

Removed: 




diff  --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp 
b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
index c004c0f3c3cf5..fbf128553fd5e 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
@@ -425,8 +425,7 @@ void RegisterInfoPOSIX_arm64::AddRegSetSME(bool has_zt) {
   //
   // This must be added now, rather than when vg is defined because SME is a
   // dynamic set that may or may not be present.
-  static uint32_t vg_invalidates[] = {sme_regnum + 1 /*svg*/,
-  LLDB_INVALID_REGNUM};
+  static uint32_t vg_invalidates[] = {GetRegNumSMESVG(), LLDB_INVALID_REGNUM};
   m_dynamic_reg_infos[GetRegNumSVEVG()].invalidate_regs = vg_invalidates;
 }
 



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


[Lldb-commits] [lldb] [LLDB] Add SI_USER and SI_KERNEL to Linux signals (PR #144800)

2025-06-19 Thread Pavel Labath via lldb-commits

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

> SI_KERNEL to my understanding usually indicates something went awry in the 
> Kernel itself

If by that you mean "a kernel bug" then the answer is no. It's really a 
catch-all code for signals originating from inside the kernel. Looking at the 
sources, it looks like this may be sent in case there's a problem with the page 
tables (which would be a kernel bug or a hardware issue), but it's also used 
for things like "insufficient space to set up a signal handler frame" (which is 
definitely an application issue) and "IO on fd is possible (and application did 
not request a specific signal to be sent)" (which isn't an issue at all).

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


[Lldb-commits] [lldb] [lldb][DWARFASTParserClang] Make GetCXXObjectParameter public and call it from unit-tests (PR #144879)

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

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

>From bda770fa0bd47fc0ac64189f5e25a9b820051d8c Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Thu, 19 Jun 2025 12:11:32 +0100
Subject: [PATCH 1/2] [lldb][DWARFASTParserClang] GetCXXObjectParameter to take
 DeclContext DIE parameter

I'm trying to call `GetCXXObjectParameter` from unit-tests in a
follow-up patch and taking a `DWARFDIE` instead of `clang::DeclContext`
makes that much simpler. These should be equivalent, since all we're
trying to check is that the parent context is a record type.
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp   | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 620501b304e63..7fc1d70898d1d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -163,14 +163,14 @@ static bool TagIsRecordType(dw_tag_t tag) {
 /// 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.
-static DWARFDIE
-GetCXXObjectParameter(const DWARFDIE &subprogram,
-  const clang::DeclContext &containing_decl_ctx) {
+static DWARFDIE GetCXXObjectParameter(const DWARFDIE &subprogram,
+  const DWARFDIE &decl_ctx_die) {
+  assert(subprogram);
   assert(subprogram.Tag() == DW_TAG_subprogram ||
  subprogram.Tag() == DW_TAG_inlined_subroutine ||
  subprogram.Tag() == DW_TAG_subroutine_type);
 
-  if (!DeclKindIsCXXClass(containing_decl_ctx.getDeclKind()))
+  if (!decl_ctx_die.IsStructUnionOrClass())
 return {};
 
   if (DWARFDIE object_parameter =
@@ -1304,8 +1304,7 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
   clang::CallingConv calling_convention =
   ConvertDWARFCallingConventionToClang(attrs);
 
-  const DWARFDIE object_parameter =
-  GetCXXObjectParameter(die, *containing_decl_ctx);
+  const DWARFDIE object_parameter = GetCXXObjectParameter(die, decl_ctx_die);
 
   // clang_type will get the function prototype clang type after this
   // call
@@ -2411,12 +2410,13 @@ 
DWARFASTParserClang::ConstructDemangledNameFromDWARF(const DWARFDIE &die) {
   DWARFDeclContext decl_ctx = die.GetDWARFDeclContext();
   sstr << decl_ctx.GetQualifiedName();
 
+  DWARFDIE decl_ctx_die;
   clang::DeclContext *containing_decl_ctx =
-  GetClangDeclContextContainingDIE(die, nullptr);
+  GetClangDeclContextContainingDIE(die, &decl_ctx_die);
   assert(containing_decl_ctx);
 
-  const unsigned cv_quals = GetCXXMethodCVQuals(
-  die, GetCXXObjectParameter(die, *containing_decl_ctx));
+  const unsigned cv_quals =
+  GetCXXMethodCVQuals(die, GetCXXObjectParameter(die, decl_ctx_die));
 
   ParseChildParameters(containing_decl_ctx, die, is_variadic,
has_template_params, param_types, param_names);

>From de7b06c9afadcf950b96e8a45d7df19dd6a590f9 Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Thu, 19 Jun 2025 12:22:30 +0100
Subject: [PATCH 2/2] [lldb][DWARFASTParserClang] Make GetCXXObjectParameter
 public and call it from unit-tests

My goal is to remove the `object_pointer` member on
`ParsedDWARFTypeAttributes` since it's duplicating information that we
retrieve with `GetCXXObjectParameter` anyway. To continue having
coverage for the `DW_AT_object_pointer` code-paths, instead of checking the
`attrs.object_pointer` I'm now calling `GetCXXObjectParameter` directly.
We could find some very roundabout way to go via the Clang AST to check
that the object parameter was parsed correctly, but that quickly became
quite painful.

Depends on https://github.com/llvm/llvm-project/pull/144876
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  |  5 ++-
 .../SymbolFile/DWARF/DWARFASTParserClang.h|  4 ++
 .../DWARF/DWARFASTParserClangTests.cpp| 38 +--
 3 files changed, 33 insertions(+), 14 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 7fc1d70898d1d..4f79c8aa3f811 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -163,8 +163,9 @@ static bool TagIsRecordType(dw_tag_t tag) {
 /// 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.
-static DWARFDIE GetCXXObjectParameter(const DWARFDIE &subprogram,
-  const DWARFDIE &decl_ctx_die) {
+DWARFDIE
+DWARFASTParserClang::GetCXXObjectParameter(const DWARFDIE &subprogram,
+   const DWARFDIE

[Lldb-commits] [lldb] [lldb][DWARFASTParserClang] GetCXXObjectParameter to take DeclContext DIE parameter (PR #144876)

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

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


[Lldb-commits] [lldb] [lldb][DWARF] Remove object_pointer from ParsedDWARFAttributes (PR #144880)

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

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

>From bda770fa0bd47fc0ac64189f5e25a9b820051d8c Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Thu, 19 Jun 2025 12:11:32 +0100
Subject: [PATCH 1/5] [lldb][DWARFASTParserClang] GetCXXObjectParameter to take
 DeclContext DIE parameter

I'm trying to call `GetCXXObjectParameter` from unit-tests in a
follow-up patch and taking a `DWARFDIE` instead of `clang::DeclContext`
makes that much simpler. These should be equivalent, since all we're
trying to check is that the parent context is a record type.
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp   | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 620501b304e63..7fc1d70898d1d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -163,14 +163,14 @@ static bool TagIsRecordType(dw_tag_t tag) {
 /// 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.
-static DWARFDIE
-GetCXXObjectParameter(const DWARFDIE &subprogram,
-  const clang::DeclContext &containing_decl_ctx) {
+static DWARFDIE GetCXXObjectParameter(const DWARFDIE &subprogram,
+  const DWARFDIE &decl_ctx_die) {
+  assert(subprogram);
   assert(subprogram.Tag() == DW_TAG_subprogram ||
  subprogram.Tag() == DW_TAG_inlined_subroutine ||
  subprogram.Tag() == DW_TAG_subroutine_type);
 
-  if (!DeclKindIsCXXClass(containing_decl_ctx.getDeclKind()))
+  if (!decl_ctx_die.IsStructUnionOrClass())
 return {};
 
   if (DWARFDIE object_parameter =
@@ -1304,8 +1304,7 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
   clang::CallingConv calling_convention =
   ConvertDWARFCallingConventionToClang(attrs);
 
-  const DWARFDIE object_parameter =
-  GetCXXObjectParameter(die, *containing_decl_ctx);
+  const DWARFDIE object_parameter = GetCXXObjectParameter(die, decl_ctx_die);
 
   // clang_type will get the function prototype clang type after this
   // call
@@ -2411,12 +2410,13 @@ 
DWARFASTParserClang::ConstructDemangledNameFromDWARF(const DWARFDIE &die) {
   DWARFDeclContext decl_ctx = die.GetDWARFDeclContext();
   sstr << decl_ctx.GetQualifiedName();
 
+  DWARFDIE decl_ctx_die;
   clang::DeclContext *containing_decl_ctx =
-  GetClangDeclContextContainingDIE(die, nullptr);
+  GetClangDeclContextContainingDIE(die, &decl_ctx_die);
   assert(containing_decl_ctx);
 
-  const unsigned cv_quals = GetCXXMethodCVQuals(
-  die, GetCXXObjectParameter(die, *containing_decl_ctx));
+  const unsigned cv_quals =
+  GetCXXMethodCVQuals(die, GetCXXObjectParameter(die, decl_ctx_die));
 
   ParseChildParameters(containing_decl_ctx, die, is_variadic,
has_template_params, param_types, param_names);

>From de7b06c9afadcf950b96e8a45d7df19dd6a590f9 Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Thu, 19 Jun 2025 12:22:30 +0100
Subject: [PATCH 2/5] [lldb][DWARFASTParserClang] Make GetCXXObjectParameter
 public and call it from unit-tests

My goal is to remove the `object_pointer` member on
`ParsedDWARFTypeAttributes` since it's duplicating information that we
retrieve with `GetCXXObjectParameter` anyway. To continue having
coverage for the `DW_AT_object_pointer` code-paths, instead of checking the
`attrs.object_pointer` I'm now calling `GetCXXObjectParameter` directly.
We could find some very roundabout way to go via the Clang AST to check
that the object parameter was parsed correctly, but that quickly became
quite painful.

Depends on https://github.com/llvm/llvm-project/pull/144876
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  |  5 ++-
 .../SymbolFile/DWARF/DWARFASTParserClang.h|  4 ++
 .../DWARF/DWARFASTParserClangTests.cpp| 38 +--
 3 files changed, 33 insertions(+), 14 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 7fc1d70898d1d..4f79c8aa3f811 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -163,8 +163,9 @@ static bool TagIsRecordType(dw_tag_t tag) {
 /// 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.
-static DWARFDIE GetCXXObjectParameter(const DWARFDIE &subprogram,
-  const DWARFDIE &decl_ctx_die) {
+DWARFDIE
+DWARFASTParserClang::GetCXXObjectParameter(const DWARFDIE &subprogram,
+   const DWARFDIE

[Lldb-commits] [lldb] [lldb][DWARF] Remove object_pointer from ParsedDWARFAttributes (PR #144880)

2025-06-19 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 h,cpp -- 
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h 
lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
``





View the diff from clang-format here.


``diff
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index d1aef8bec..bdd06eda3 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -1316,8 +1316,8 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
 ParseObjCMethod(*objc_method, die, clang_type, attrs, is_variadic);
   } else if (is_cxx_method) {
 auto [handled, type_sp] =
-ParseCXXMethod(die, clang_type, attrs, decl_ctx_die, 
object_parameter,
-   ignore_containing_context);
+ParseCXXMethod(die, clang_type, attrs, decl_ctx_die,
+   object_parameter, ignore_containing_context);
 if (type_sp)
   return type_sp;
 

``




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


[Lldb-commits] [lldb] [lldb/cmake][WIP] Plugin layering enforcement mechanism (PR #144543)

2025-06-19 Thread Pavel Labath via lldb-commits

https://github.com/labath updated 
https://github.com/llvm/llvm-project/pull/144543

>From d33eec81bf9895857e752d3a7e6708aaebaccea0 Mon Sep 17 00:00:00 2001
From: Pavel Labath 
Date: Tue, 17 Jun 2025 16:54:53 +0200
Subject: [PATCH 1/2] [lldb/cmake] Plugin layering enforcement mechanism

---
 lldb/CMakeLists.txt   |  3 +
 lldb/cmake/modules/LLDBLayeringCheck.cmake| 68 +++
 lldb/source/Plugins/ABI/CMakeLists.txt|  6 ++
 .../Plugins/Architecture/CMakeLists.txt   |  2 +
 .../Plugins/Disassembler/CMakeLists.txt   |  2 +
 .../Plugins/DynamicLoader/CMakeLists.txt  |  7 ++
 .../Plugins/ExpressionParser/CMakeLists.txt   |  2 +
 .../source/Plugins/Instruction/CMakeLists.txt |  2 +
 .../InstrumentationRuntime/CMakeLists.txt |  2 +
 lldb/source/Plugins/JITLoader/CMakeLists.txt  |  3 +
 lldb/source/Plugins/Language/CMakeLists.txt   |  6 ++
 .../Plugins/LanguageRuntime/CMakeLists.txt|  3 +
 .../Plugins/MemoryHistory/CMakeLists.txt  |  2 +
 .../Plugins/ObjectContainer/CMakeLists.txt|  2 +
 lldb/source/Plugins/ObjectFile/CMakeLists.txt |  2 +
 .../Plugins/OperatingSystem/CMakeLists.txt|  2 +
 lldb/source/Plugins/Platform/CMakeLists.txt   |  7 ++
 lldb/source/Plugins/Process/CMakeLists.txt|  5 ++
 .../Plugins/Process/Utility/CMakeLists.txt|  3 +
 lldb/source/Plugins/REPL/CMakeLists.txt   |  3 +
 .../RegisterTypeBuilder/CMakeLists.txt|  2 +
 .../Plugins/ScriptInterpreter/CMakeLists.txt  |  2 +
 .../Plugins/StructuredData/CMakeLists.txt |  2 +
 lldb/source/Plugins/SymbolFile/CMakeLists.txt |  7 ++
 .../Plugins/SymbolLocator/CMakeLists.txt  |  2 +
 .../Plugins/SymbolVendor/CMakeLists.txt   |  3 +
 .../Plugins/SystemRuntime/CMakeLists.txt  |  3 +
 lldb/source/Plugins/Trace/CMakeLists.txt  |  2 +
 .../Plugins/TraceExporter/CMakeLists.txt  |  2 +
 lldb/source/Plugins/TypeSystem/CMakeLists.txt |  4 ++
 .../Plugins/UnwindAssembly/CMakeLists.txt |  2 +
 31 files changed, 163 insertions(+)
 create mode 100644 lldb/cmake/modules/LLDBLayeringCheck.cmake

diff --git a/lldb/CMakeLists.txt b/lldb/CMakeLists.txt
index 2aaf75dd87bc3..e3b72e94d4beb 100644
--- a/lldb/CMakeLists.txt
+++ b/lldb/CMakeLists.txt
@@ -37,6 +37,7 @@ endif()
 
 include(LLDBConfig)
 include(AddLLDB)
+include(LLDBLayeringCheck)
 
 set(LLDB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
 
@@ -127,6 +128,8 @@ add_subdirectory(source)
 add_subdirectory(tools)
 add_subdirectory(docs)
 
+check_lldb_plugin_layering()
+
 if (LLDB_ENABLE_PYTHON)
   if(LLDB_BUILD_FRAMEWORK)
 set(lldb_python_target_dir 
"${LLDB_FRAMEWORK_ABSOLUTE_BUILD_DIR}/LLDB.framework/Resources/Python/lldb")
diff --git a/lldb/cmake/modules/LLDBLayeringCheck.cmake 
b/lldb/cmake/modules/LLDBLayeringCheck.cmake
new file mode 100644
index 0..082bbe37a980f
--- /dev/null
+++ b/lldb/cmake/modules/LLDBLayeringCheck.cmake
@@ -0,0 +1,68 @@
+define_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND)
+define_property(TARGET PROPERTY LLDB_PLUGIN_KIND INHERITED)
+
+define_property(DIRECTORY PROPERTY LLDB_ACCEPTABLE_PLUGIN_DEPENDENCIES)
+define_property(TARGET PROPERTY LLDB_ACCEPTABLE_PLUGIN_DEPENDENCIES INHERITED)
+
+define_property(DIRECTORY PROPERTY LLDB_TOLERATED_PLUGIN_DEPENDENCIES)
+define_property(TARGET PROPERTY LLDB_TOLERATED_PLUGIN_DEPENDENCIES INHERITED)
+
+option(LLDB_GENERATE_PLUGIN_DEP_GRAPH OFF)
+
+function(check_lldb_plugin_layering)
+  get_property(plugins GLOBAL PROPERTY LLDB_PLUGINS)
+  foreach(plugin ${plugins})
+get_property(plugin_kind TARGET ${plugin} PROPERTY LLDB_PLUGIN_KIND)
+get_property(acceptable_deps TARGET ${plugin}
+  PROPERTY LLDB_ACCEPTABLE_PLUGIN_DEPENDENCIES)
+get_property(tolerated_deps TARGET ${plugin}
+  PROPERTY LLDB_TOLERATED_PLUGIN_DEPENDENCIES)
+
+# A plugin is always permitted to depend on its own kind for the purposes
+# subclassing. Ideally the intra-kind dependencies should not form a loop,
+# but we're not checking that here.
+list(APPEND acceptable_deps ${plugin_kind})
+
+list(APPEND all_plugin_kinds ${plugin_kind})
+
+get_property(link_libs TARGET ${plugin} PROPERTY LINK_LIBRARIES)
+foreach(link_lib ${link_libs})
+  if(link_lib IN_LIST plugins)
+get_property(lib_kind TARGET ${link_lib} PROPERTY LLDB_PLUGIN_KIND)
+if (lib_kind)
+  if (lib_kind IN_LIST acceptable_deps)
+set(dep_kind green)
+  elseif (lib_kind IN_LIST tolerated_deps)
+set(dep_kind yellow)
+  else()
+set(dep_kind red)
+message(SEND_ERROR "Plugin ${plugin} cannot depend on ${lib_kind} "
+  "plugin ${link_lib}")
+  endif()
+  list(APPEND dep_${dep_kind}_${plugin_kind}_${lib_kind} ${plugin})
+endif()
+  endif()
+endforeach()
+  endforeach()
+
+  if (LLDB_GENERATE_PLUGIN_DEP_GRAPH)
+set(dep_graph "digraph Plugins {\n")
+list(REMOVE_DUPLICATES all_plugin_kinds)
+foreach (from ${all

[Lldb-commits] [lldb] [lldb][DWARF] Remove object_pointer from ParsedDWARFAttributes (PR #144880)

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

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

>From bda770fa0bd47fc0ac64189f5e25a9b820051d8c Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Thu, 19 Jun 2025 12:11:32 +0100
Subject: [PATCH 1/4] [lldb][DWARFASTParserClang] GetCXXObjectParameter to take
 DeclContext DIE parameter

I'm trying to call `GetCXXObjectParameter` from unit-tests in a
follow-up patch and taking a `DWARFDIE` instead of `clang::DeclContext`
makes that much simpler. These should be equivalent, since all we're
trying to check is that the parent context is a record type.
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp   | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 620501b304e63..7fc1d70898d1d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -163,14 +163,14 @@ static bool TagIsRecordType(dw_tag_t tag) {
 /// 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.
-static DWARFDIE
-GetCXXObjectParameter(const DWARFDIE &subprogram,
-  const clang::DeclContext &containing_decl_ctx) {
+static DWARFDIE GetCXXObjectParameter(const DWARFDIE &subprogram,
+  const DWARFDIE &decl_ctx_die) {
+  assert(subprogram);
   assert(subprogram.Tag() == DW_TAG_subprogram ||
  subprogram.Tag() == DW_TAG_inlined_subroutine ||
  subprogram.Tag() == DW_TAG_subroutine_type);
 
-  if (!DeclKindIsCXXClass(containing_decl_ctx.getDeclKind()))
+  if (!decl_ctx_die.IsStructUnionOrClass())
 return {};
 
   if (DWARFDIE object_parameter =
@@ -1304,8 +1304,7 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
   clang::CallingConv calling_convention =
   ConvertDWARFCallingConventionToClang(attrs);
 
-  const DWARFDIE object_parameter =
-  GetCXXObjectParameter(die, *containing_decl_ctx);
+  const DWARFDIE object_parameter = GetCXXObjectParameter(die, decl_ctx_die);
 
   // clang_type will get the function prototype clang type after this
   // call
@@ -2411,12 +2410,13 @@ 
DWARFASTParserClang::ConstructDemangledNameFromDWARF(const DWARFDIE &die) {
   DWARFDeclContext decl_ctx = die.GetDWARFDeclContext();
   sstr << decl_ctx.GetQualifiedName();
 
+  DWARFDIE decl_ctx_die;
   clang::DeclContext *containing_decl_ctx =
-  GetClangDeclContextContainingDIE(die, nullptr);
+  GetClangDeclContextContainingDIE(die, &decl_ctx_die);
   assert(containing_decl_ctx);
 
-  const unsigned cv_quals = GetCXXMethodCVQuals(
-  die, GetCXXObjectParameter(die, *containing_decl_ctx));
+  const unsigned cv_quals =
+  GetCXXMethodCVQuals(die, GetCXXObjectParameter(die, decl_ctx_die));
 
   ParseChildParameters(containing_decl_ctx, die, is_variadic,
has_template_params, param_types, param_names);

>From de7b06c9afadcf950b96e8a45d7df19dd6a590f9 Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Thu, 19 Jun 2025 12:22:30 +0100
Subject: [PATCH 2/4] [lldb][DWARFASTParserClang] Make GetCXXObjectParameter
 public and call it from unit-tests

My goal is to remove the `object_pointer` member on
`ParsedDWARFTypeAttributes` since it's duplicating information that we
retrieve with `GetCXXObjectParameter` anyway. To continue having
coverage for the `DW_AT_object_pointer` code-paths, instead of checking the
`attrs.object_pointer` I'm now calling `GetCXXObjectParameter` directly.
We could find some very roundabout way to go via the Clang AST to check
that the object parameter was parsed correctly, but that quickly became
quite painful.

Depends on https://github.com/llvm/llvm-project/pull/144876
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  |  5 ++-
 .../SymbolFile/DWARF/DWARFASTParserClang.h|  4 ++
 .../DWARF/DWARFASTParserClangTests.cpp| 38 +--
 3 files changed, 33 insertions(+), 14 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 7fc1d70898d1d..4f79c8aa3f811 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -163,8 +163,9 @@ static bool TagIsRecordType(dw_tag_t tag) {
 /// 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.
-static DWARFDIE GetCXXObjectParameter(const DWARFDIE &subprogram,
-  const DWARFDIE &decl_ctx_die) {
+DWARFDIE
+DWARFASTParserClang::GetCXXObjectParameter(const DWARFDIE &subprogram,
+   const DWARFDIE

[Lldb-commits] [lldb] [lldb] Disable TestTargetWatchAddress on Windows x86_64 (PR #144779)

2025-06-19 Thread Pavel Labath via lldb-commits

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


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


[Lldb-commits] [lldb] [lldb] Disable TestTargetWatchAddress on Windows x86_64 (PR #144779)

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

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


[Lldb-commits] [lldb] 3e795c6 - [lldb] Disable TestTargetWatchAddress on Windows x86_64 (#144779)

2025-06-19 Thread via lldb-commits

Author: Dmitry Vasilyev
Date: 2025-06-19T11:12:34+04:00
New Revision: 3e795c60c73e990fbbf254715cb47855c32bcfae

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

LOG: [lldb] Disable TestTargetWatchAddress on Windows x86_64 (#144779)

See #144777 for details.

Added: 


Modified: 
lldb/test/API/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py

Removed: 




diff  --git 
a/lldb/test/API/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py 
b/lldb/test/API/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py
index 37fa911b3714c..f1c7a60300df5 100644
--- 
a/lldb/test/API/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py
+++ 
b/lldb/test/API/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py
@@ -21,6 +21,11 @@ def setUp(self):
 # This is for verifying that watch location works.
 self.violating_func = "do_bad_thing_with_location"
 
+@skipIf(
+oslist=["windows"],
+archs=["x86_64"],
+bugnumber="github.com/llvm/llvm-project/issues/144777",
+)
 def test_watch_create_by_address(self):
 """Exercise SBTarget.WatchpointCreateByAddress() API to set a 
watchpoint."""
 self.build()
@@ -88,6 +93,11 @@ def test_watch_create_by_address(self):
 
 # This finishes our test.
 
+@skipIf(
+oslist=["windows"],
+archs=["x86_64"],
+bugnumber="github.com/llvm/llvm-project/issues/144777",
+)
 def test_watch_address(self):
 """Exercise SBTarget.WatchAddress() API to set a watchpoint.
 Same as test_watch_create_by_address, but uses the simpler API.



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