[Lldb-commits] [lldb] [lldb-dap] Adding support for well typed events. (PR #130104)
John Harrison via lldb-commits
lldb-commits at lists.llvm.org
Mon Mar 17 14:24:38 PDT 2025
https://github.com/ashgti updated https://github.com/llvm/llvm-project/pull/130104
>From 2c51a8bdb27764a358e76e554d693a4af57074fc Mon Sep 17 00:00:00 2001
From: John Harrison <harjohn at google.com>
Date: Thu, 6 Mar 2025 14:13:58 +0100
Subject: [PATCH] [lldb-dap] Adding support for well typed events.
This adds a mechanism for registering well typed events with the DAP.
For a proof of concept, this updates the 'exited' and the 'process'
event to use the new protocol serialization handlers and updates the
call sites to use the new helper.
---
lldb/tools/lldb-dap/CMakeLists.txt | 6 +-
lldb/tools/lldb-dap/DAP.cpp | 5 +-
lldb/tools/lldb-dap/DAP.h | 14 +++
lldb/tools/lldb-dap/EventHelper.cpp | 90 -------------------
lldb/tools/lldb-dap/EventHelper.h | 6 --
lldb/tools/lldb-dap/Events/EventHandler.h | 57 ++++++++++++
.../lldb-dap/Events/ExitedEventHandler.cpp | 20 +++++
.../lldb-dap/Events/ProcessEventHandler.cpp | 34 +++++++
.../lldb-dap/Handler/AttachRequestHandler.cpp | 2 +-
.../Handler/InitializeRequestHandler.cpp | 2 +-
.../lldb-dap/Handler/LaunchRequestHandler.cpp | 5 +-
lldb/tools/lldb-dap/Protocol/ProtocolBase.h | 4 +-
.../lldb-dap/Protocol/ProtocolEvents.cpp | 46 ++++++++++
lldb/tools/lldb-dap/Protocol/ProtocolEvents.h | 76 ++++++++++++++++
lldb/tools/lldb-dap/lldb-dap.cpp | 1 +
15 files changed, 262 insertions(+), 106 deletions(-)
create mode 100644 lldb/tools/lldb-dap/Events/EventHandler.h
create mode 100644 lldb/tools/lldb-dap/Events/ExitedEventHandler.cpp
create mode 100644 lldb/tools/lldb-dap/Events/ProcessEventHandler.cpp
create mode 100644 lldb/tools/lldb-dap/Protocol/ProtocolEvents.cpp
create mode 100644 lldb/tools/lldb-dap/Protocol/ProtocolEvents.h
diff --git a/lldb/tools/lldb-dap/CMakeLists.txt b/lldb/tools/lldb-dap/CMakeLists.txt
index adad75a79fa7a..54e6f3ead2695 100644
--- a/lldb/tools/lldb-dap/CMakeLists.txt
+++ b/lldb/tools/lldb-dap/CMakeLists.txt
@@ -37,6 +37,9 @@ add_lldb_tool(lldb-dap
Transport.cpp
Watchpoint.cpp
+ Events/ExitedEventHandler.cpp
+ Events/ProcessEventHandler.cpp
+
Handler/ResponseHandler.cpp
Handler/AttachRequestHandler.cpp
Handler/BreakpointLocationsHandler.cpp
@@ -75,8 +78,9 @@ add_lldb_tool(lldb-dap
Handler/VariablesRequestHandler.cpp
Protocol/ProtocolBase.cpp
- Protocol/ProtocolTypes.cpp
+ Protocol/ProtocolEvents.cpp
Protocol/ProtocolRequests.cpp
+ Protocol/ProtocolTypes.cpp
LINK_LIBS
liblldb
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index a1e2187288768..a2ae96eb5d967 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -8,6 +8,7 @@
#include "DAP.h"
#include "DAPLog.h"
+#include "Events/EventHandler.h"
#include "Handler/RequestHandler.h"
#include "Handler/ResponseHandler.h"
#include "JSONUtils.h"
@@ -82,7 +83,9 @@ DAP::DAP(llvm::StringRef path, std::ofstream *log,
configuration_done_sent(false), waiting_for_run_in_terminal(false),
progress_event_reporter(
[&](const ProgressEvent &event) { SendJSON(event.ToJSON()); }),
- reverse_request_seq(0), repl_mode(default_repl_mode) {}
+ reverse_request_seq(0), repl_mode(default_repl_mode),
+ onExited(ExitedEventHandler(*this)),
+ onProcess(ProcessEventHandler(*this)) {}
DAP::~DAP() = default;
diff --git a/lldb/tools/lldb-dap/DAP.h b/lldb/tools/lldb-dap/DAP.h
index 4c57f9fef3d89..fe902e670cf04 100644
--- a/lldb/tools/lldb-dap/DAP.h
+++ b/lldb/tools/lldb-dap/DAP.h
@@ -58,6 +58,9 @@ typedef llvm::StringMap<FunctionBreakpoint> FunctionBreakpointMap;
typedef llvm::DenseMap<lldb::addr_t, InstructionBreakpoint>
InstructionBreakpointMap;
+/// A debug adapter initiated event.
+template <typename... Args> using OutgoingEvent = std::function<void(Args...)>;
+
enum class OutputType { Console, Stdout, Stderr, Telemetry };
/// Buffer size for handling output events.
@@ -230,6 +233,17 @@ struct DAP {
void operator=(const DAP &rhs) = delete;
/// @}
+ /// Typed Events Handlers
+ /// @{
+
+ /// onExited sends an event that the debuggee has exited.
+ OutgoingEvent<> onExited;
+ /// onProcess sends an event that indicates that the debugger has begun
+ /// debugging a new process.
+ OutgoingEvent<> onProcess;
+
+ /// @}
+
ExceptionBreakpoint *GetExceptionBreakpoint(const std::string &filter);
ExceptionBreakpoint *GetExceptionBreakpoint(const lldb::break_id_t bp_id);
diff --git a/lldb/tools/lldb-dap/EventHelper.cpp b/lldb/tools/lldb-dap/EventHelper.cpp
index 705eb0a457d9c..7908674eb4642 100644
--- a/lldb/tools/lldb-dap/EventHelper.cpp
+++ b/lldb/tools/lldb-dap/EventHelper.cpp
@@ -32,87 +32,6 @@ static void SendThreadExitedEvent(DAP &dap, lldb::tid_t tid) {
dap.SendJSON(llvm::json::Value(std::move(event)));
}
-// "ProcessEvent": {
-// "allOf": [
-// { "$ref": "#/definitions/Event" },
-// {
-// "type": "object",
-// "description": "Event message for 'process' event type. The event
-// indicates that the debugger has begun debugging a
-// new process. Either one that it has launched, or one
-// that it has attached to.",
-// "properties": {
-// "event": {
-// "type": "string",
-// "enum": [ "process" ]
-// },
-// "body": {
-// "type": "object",
-// "properties": {
-// "name": {
-// "type": "string",
-// "description": "The logical name of the process. This is
-// usually the full path to process's executable
-// file. Example: /home/myproj/program.js."
-// },
-// "systemProcessId": {
-// "type": "integer",
-// "description": "The system process id of the debugged process.
-// This property will be missing for non-system
-// processes."
-// },
-// "isLocalProcess": {
-// "type": "boolean",
-// "description": "If true, the process is running on the same
-// computer as the debug adapter."
-// },
-// "startMethod": {
-// "type": "string",
-// "enum": [ "launch", "attach", "attachForSuspendedLaunch" ],
-// "description": "Describes how the debug engine started
-// debugging this process.",
-// "enumDescriptions": [
-// "Process was launched under the debugger.",
-// "Debugger attached to an existing process.",
-// "A project launcher component has launched a new process in
-// a suspended state and then asked the debugger to attach."
-// ]
-// }
-// },
-// "required": [ "name" ]
-// }
-// },
-// "required": [ "event", "body" ]
-// }
-// ]
-// }
-void SendProcessEvent(DAP &dap, LaunchMethod launch_method) {
- lldb::SBFileSpec exe_fspec = dap.target.GetExecutable();
- char exe_path[PATH_MAX];
- exe_fspec.GetPath(exe_path, sizeof(exe_path));
- llvm::json::Object event(CreateEventObject("process"));
- llvm::json::Object body;
- EmplaceSafeString(body, "name", std::string(exe_path));
- const auto pid = dap.target.GetProcess().GetProcessID();
- body.try_emplace("systemProcessId", (int64_t)pid);
- body.try_emplace("isLocalProcess", true);
- const char *startMethod = nullptr;
- switch (launch_method) {
- case Launch:
- startMethod = "launch";
- break;
- case Attach:
- startMethod = "attach";
- break;
- case AttachForSuspendedLaunch:
- startMethod = "attachForSuspendedLaunch";
- break;
- }
- body.try_emplace("startMethod", startMethod);
- event.try_emplace("body", std::move(body));
- dap.SendJSON(llvm::json::Value(std::move(event)));
-}
-
// Send a thread stopped event for all threads as long as the process
// is stopped.
void SendThreadStoppedEvent(DAP &dap) {
@@ -235,13 +154,4 @@ void SendContinuedEvent(DAP &dap) {
dap.SendJSON(llvm::json::Value(std::move(event)));
}
-// Send a "exited" event to indicate the process has exited.
-void SendProcessExitedEvent(DAP &dap, lldb::SBProcess &process) {
- llvm::json::Object event(CreateEventObject("exited"));
- llvm::json::Object body;
- body.try_emplace("exitCode", (int64_t)process.GetExitStatus());
- event.try_emplace("body", std::move(body));
- dap.SendJSON(llvm::json::Value(std::move(event)));
-}
-
} // namespace lldb_dap
diff --git a/lldb/tools/lldb-dap/EventHelper.h b/lldb/tools/lldb-dap/EventHelper.h
index 90b009c73089e..e6a54e63d00df 100644
--- a/lldb/tools/lldb-dap/EventHelper.h
+++ b/lldb/tools/lldb-dap/EventHelper.h
@@ -14,10 +14,6 @@
namespace lldb_dap {
struct DAP;
-enum LaunchMethod { Launch, Attach, AttachForSuspendedLaunch };
-
-void SendProcessEvent(DAP &dap, LaunchMethod launch_method);
-
void SendThreadStoppedEvent(DAP &dap);
void SendTerminatedEvent(DAP &dap);
@@ -26,8 +22,6 @@ void SendStdOutStdErr(DAP &dap, lldb::SBProcess &process);
void SendContinuedEvent(DAP &dap);
-void SendProcessExitedEvent(DAP &dap, lldb::SBProcess &process);
-
} // namespace lldb_dap
#endif
diff --git a/lldb/tools/lldb-dap/Events/EventHandler.h b/lldb/tools/lldb-dap/Events/EventHandler.h
new file mode 100644
index 0000000000000..f0fac0d635ce2
--- /dev/null
+++ b/lldb/tools/lldb-dap/Events/EventHandler.h
@@ -0,0 +1,57 @@
+//===-- EventHandler.h ----------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_TOOLS_LLDB_DAP_EVENTS_EVENT_HANDLER
+#define LLDB_TOOLS_LLDB_DAP_EVENTS_EVENT_HANDLER
+
+#include "DAP.h"
+#include "Protocol/ProtocolBase.h"
+#include "Protocol/ProtocolEvents.h"
+#include "lldb/API/SBProcess.h"
+
+namespace lldb_dap {
+
+template <typename Body, typename... Args> class BaseEventHandler {
+public:
+ BaseEventHandler(DAP &dap) : dap(dap) {}
+
+ virtual ~BaseEventHandler() = default;
+
+ virtual llvm::StringLiteral getEvent() const = 0;
+ virtual Body Handler(Args...) const = 0;
+
+ void operator()(Args... args) const {
+ Body body = Handler(args...);
+ protocol::Event event{/*event=*/getEvent().str(), /*body=*/std::move(body)};
+ dap.Send(event);
+ }
+
+protected:
+ DAP &dap;
+};
+
+/// Handler for the event indicates that the debuggee has exited and returns its
+/// exit code.
+class ExitedEventHandler : public BaseEventHandler<protocol::ExitedEventBody> {
+public:
+ using BaseEventHandler::BaseEventHandler;
+ llvm::StringLiteral getEvent() const override { return "exited"; }
+ protocol::ExitedEventBody Handler() const override;
+};
+
+class ProcessEventHandler
+ : public BaseEventHandler<protocol::ProcessEventBody> {
+public:
+ using BaseEventHandler::BaseEventHandler;
+ llvm::StringLiteral getEvent() const override { return "process"; }
+ protocol::ProcessEventBody Handler() const override;
+};
+
+} // end namespace lldb_dap
+
+#endif
diff --git a/lldb/tools/lldb-dap/Events/ExitedEventHandler.cpp b/lldb/tools/lldb-dap/Events/ExitedEventHandler.cpp
new file mode 100644
index 0000000000000..010b2df3de456
--- /dev/null
+++ b/lldb/tools/lldb-dap/Events/ExitedEventHandler.cpp
@@ -0,0 +1,20 @@
+//===-- ExitedEventHandler.cpp --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Events/EventHandler.h"
+#include "lldb/API/SBProcess.h"
+
+namespace lldb_dap {
+
+protocol::ExitedEventBody ExitedEventHandler::Handler() const {
+ protocol::ExitedEventBody body;
+ body.exitCode = dap.target.GetProcess().GetExitStatus();
+ return body;
+}
+
+} // namespace lldb_dap
diff --git a/lldb/tools/lldb-dap/Events/ProcessEventHandler.cpp b/lldb/tools/lldb-dap/Events/ProcessEventHandler.cpp
new file mode 100644
index 0000000000000..52b3ae1982126
--- /dev/null
+++ b/lldb/tools/lldb-dap/Events/ProcessEventHandler.cpp
@@ -0,0 +1,34 @@
+//===-- ProcessEventHandler.cpp -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Events/EventHandler.h"
+#include "Protocol/ProtocolEvents.h"
+#include "lldb/API/SBProcess.h"
+#include "lldb/API/SBTarget.h"
+
+using namespace llvm;
+using namespace lldb_dap::protocol;
+
+namespace lldb_dap {
+
+ProcessEventBody ProcessEventHandler::Handler() const {
+ ProcessEventBody body;
+
+ char path[PATH_MAX] = {0};
+ dap.target.GetExecutable().GetPath(path, sizeof(path));
+ body.name = path;
+ body.systemProcessId = dap.target.GetProcess().GetProcessID();
+ body.isLocalProcess = dap.target.GetPlatform().GetName() ==
+ lldb::SBPlatform::GetHostPlatform().GetName();
+ body.startMethod = dap.is_attach ? ProcessEventBody::StartMethod::attach
+ : ProcessEventBody::StartMethod::launch;
+ body.pointerSize = dap.target.GetAddressByteSize();
+ return body;
+}
+
+} // namespace lldb_dap
diff --git a/lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp
index 20f7c80a1ed90..95516610eb5b5 100644
--- a/lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp
@@ -201,7 +201,7 @@ void AttachRequestHandler::operator()(const llvm::json::Object &request) const {
dap.SendJSON(llvm::json::Value(std::move(response)));
if (error.Success()) {
- SendProcessEvent(dap, Attach);
+ dap.onProcess();
dap.SendJSON(CreateEventObject("initialized"));
}
}
diff --git a/lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp
index 3262b70042a0e..d9b905b6914cc 100644
--- a/lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp
@@ -178,7 +178,7 @@ static void EventThreadFunction(DAP &dap) {
// Run any exit LLDB commands the user specified in the
// launch.json
dap.RunExitCommands();
- SendProcessExitedEvent(dap, process);
+ dap.onExited();
dap.SendTerminatedEvent();
done = true;
}
diff --git a/lldb/tools/lldb-dap/Handler/LaunchRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/LaunchRequestHandler.cpp
index f64c186376a36..2c8dddef9bde5 100644
--- a/lldb/tools/lldb-dap/Handler/LaunchRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/LaunchRequestHandler.cpp
@@ -124,10 +124,7 @@ void LaunchRequestHandler::operator()(const llvm::json::Object &request) const {
dap.SendJSON(llvm::json::Value(std::move(response)));
if (!status.Fail()) {
- if (dap.is_attach)
- SendProcessEvent(dap, Attach); // this happens when doing runInTerminal
- else
- SendProcessEvent(dap, Launch);
+ dap.onProcess();
}
dap.SendJSON(CreateEventObject("initialized"));
}
diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolBase.h b/lldb/tools/lldb-dap/Protocol/ProtocolBase.h
index e10a903b80aaa..2ddfeb8ae0852 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolBase.h
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolBase.h
@@ -17,8 +17,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_TOOLS_LLDB_DAP_PROTOCOL_H
-#define LLDB_TOOLS_LLDB_DAP_PROTOCOL_H
+#ifndef LLDB_TOOLS_LLDB_DAP_PROTOCOL_PROTOCOL_BASE_H
+#define LLDB_TOOLS_LLDB_DAP_PROTOCOL_PROTOCOL_BASE_H
#include "llvm/Support/JSON.h"
#include <cstdint>
diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolEvents.cpp b/lldb/tools/lldb-dap/Protocol/ProtocolEvents.cpp
new file mode 100644
index 0000000000000..5c0eb911408e7
--- /dev/null
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolEvents.cpp
@@ -0,0 +1,46 @@
+//===-- ProtocolEvents.cpp ------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Protocol/ProtocolEvents.h"
+#include "llvm/Support/JSON.h"
+
+using namespace llvm;
+
+namespace lldb_dap::protocol {
+
+json::Value toJSON(const ExitedEventBody &EEB) {
+ return json::Object{{"exitCode", EEB.exitCode}};
+}
+
+json::Value toJSON(const ProcessEventBody::StartMethod &m) {
+ switch (m) {
+ case ProcessEventBody::StartMethod::launch:
+ return "launch";
+ case ProcessEventBody::StartMethod::attach:
+ return "attach";
+ case ProcessEventBody::StartMethod::attachForSuspendedLaunch:
+ return "attachForSuspendedLaunch";
+ }
+}
+
+json::Value toJSON(const ProcessEventBody &PEB) {
+ json::Object result{{"name", PEB.name}};
+
+ if (PEB.systemProcessId)
+ result.insert({"systemProcessId", PEB.systemProcessId});
+ if (PEB.isLocalProcess)
+ result.insert({"isLocalProcess", PEB.isLocalProcess});
+ if (PEB.startMethod)
+ result.insert({"startMethod", PEB.startMethod});
+ if (PEB.pointerSize)
+ result.insert({"pointerSize", PEB.pointerSize});
+
+ return std::move(result);
+}
+
+} // namespace lldb_dap::protocol
diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolEvents.h b/lldb/tools/lldb-dap/Protocol/ProtocolEvents.h
new file mode 100644
index 0000000000000..58601008341b2
--- /dev/null
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolEvents.h
@@ -0,0 +1,76 @@
+//===-- ProtocolBase.h ----------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains POD structs based on the DAP specification at
+// https://microsoft.github.io/debug-adapter-protocol/specification
+//
+// This is not meant to be a complete implementation, new interfaces are added
+// when they're needed.
+//
+// Each struct has a toJSON and fromJSON function, that converts between
+// the struct and a JSON representation. (See JSON.h)
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_TOOLS_LLDB_DAP_PROTOCOL_PROTOCOL_EVENTS_H
+#define LLDB_TOOLS_LLDB_DAP_PROTOCOL_PROTOCOL_EVENTS_H
+
+#include "lldb/lldb-types.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/JSON.h"
+
+namespace lldb_dap::protocol {
+
+// MARK: Events
+
+/// The event indicates that the debuggee has exited and returns its exit code.
+struct ExitedEventBody {
+ static llvm::StringLiteral getEvent() { return "exited"; }
+
+ /// The exit code returned from the debuggee.
+ int exitCode;
+};
+llvm::json::Value toJSON(const ExitedEventBody &);
+
+/// The event indicates that the debugger has begun debugging a new process.
+/// Either one that it has launched, or one that it has attached to.
+struct ProcessEventBody {
+ /// The logical name of the process. This is usually the full path to
+ /// process's executable file. Example: /home/example/myproj/program.js.
+ std::string name;
+
+ /// The process ID of the debugged process, as assigned by the operating
+ /// system. This property should be omitted for logical processes that do not
+ /// map to operating system processes on the machine.
+ std::optional<lldb::pid_t> systemProcessId;
+
+ /// If true, the process is running on the same computer as the debug adapter.
+ std::optional<bool> isLocalProcess;
+
+ enum class StartMethod {
+ /// Process was launched under the debugger.
+ launch,
+ /// Debugger attached to an existing process.
+ attach,
+ /// A project launcher component has launched a new process in a suspended
+ /// state and then asked the debugger to attach.
+ attachForSuspendedLaunch
+ };
+
+ /// Describes how the debug engine started debugging this process.
+ std::optional<StartMethod> startMethod;
+
+ /// The size of a pointer or address for this process, in bits. This value may
+ /// be used by clients when formatting addresses for display.
+ std::optional<int> pointerSize;
+};
+llvm::json::Value toJSON(const ProcessEventBody &);
+
+} // namespace lldb_dap::protocol
+
+#endif
diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
index 59e31cf8e2cc8..f2ff2c48d5afc 100644
--- a/lldb/tools/lldb-dap/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/lldb-dap.cpp
@@ -9,6 +9,7 @@
#include "DAP.h"
#include "DAPLog.h"
#include "EventHelper.h"
+#include "Events/EventHandler.h"
#include "Handler/RequestHandler.h"
#include "RunInTerminal.h"
#include "Transport.h"
More information about the lldb-commits
mailing list