[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