[Lldb-commits] [lldb] 4f991cc - [lldb-dap] Make connection URLs match lldb (#144770)
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)
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)
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)
@@ -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)
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)
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)
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)
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)
@@ -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)
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)
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)
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)
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)
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)
@@ -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)
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)
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)
@@ -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)
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)
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)
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)
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)
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)
@@ -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)
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)
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)
@@ -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)
@@ -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)
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)
@@ -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)
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)
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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
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)
@@ -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)
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)
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)
@@ -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)
@@ -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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
@@ -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)
@@ -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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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