brintos

brintos / llvm-project-archived public Read only

0
0
Text · 24.0 KiB · 5d23535 Raw
653 lines · c
1//===-- Request.h ---------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_TOOLS_LLDB_DAP_HANDLER_HANDLER_H10#define LLDB_TOOLS_LLDB_DAP_HANDLER_HANDLER_H11 12#include "DAP.h"13#include "DAPError.h"14#include "DAPLog.h"15#include "Protocol/ProtocolBase.h"16#include "Protocol/ProtocolRequests.h"17#include "Protocol/ProtocolTypes.h"18#include "llvm/ADT/DenseSet.h"19#include "llvm/ADT/StringRef.h"20#include "llvm/Support/Error.h"21#include "llvm/Support/JSON.h"22#include <optional>23#include <type_traits>24#include <variant>25#include <vector>26 27template <typename T> struct is_optional : std::false_type {};28 29template <typename T> struct is_optional<std::optional<T>> : std::true_type {};30 31template <typename T>32inline constexpr bool is_optional_v = is_optional<T>::value;33 34namespace lldb_dap {35struct DAP;36 37/// Base class for request handlers. Do not extend this directly: Extend38/// the RequestHandler template subclass instead.39class BaseRequestHandler {40public:41  BaseRequestHandler(DAP &dap) : dap(dap) {}42 43  /// BaseRequestHandler are not copyable.44  /// @{45  BaseRequestHandler(const BaseRequestHandler &) = delete;46  BaseRequestHandler &operator=(const BaseRequestHandler &) = delete;47  /// @}48 49  virtual ~BaseRequestHandler() = default;50 51  void Run(const protocol::Request &);52 53  virtual void operator()(const protocol::Request &request) const = 0;54 55  using FeatureSet = llvm::SmallDenseSet<AdapterFeature, 1>;56  virtual FeatureSet GetSupportedFeatures() const { return {}; }57 58protected:59  /// Helpers used by multiple request handlers.60  /// FIXME: Move these into the DAP class?61  /// @{62 63  /// Prints a welcome message on the editor if the preprocessor variable64  /// LLDB_DAP_WELCOME_MESSAGE is defined.65  void PrintWelcomeMessage() const;66 67  // Takes a LaunchRequest object and launches the process, also handling68  // runInTerminal if applicable. It doesn't do any of the additional69  // initialization and bookkeeping stuff that is needed for `request_launch`.70  // This way we can reuse the process launching logic for RestartRequest too.71  llvm::Error72  LaunchProcess(const protocol::LaunchRequestArguments &request) const;73 74  // Check if the step-granularity is `instruction`.75  bool HasInstructionGranularity(const llvm::json::Object &request) const;76 77  /// @}78 79  DAP &dap;80};81 82/// FIXME: Migrate callers to typed RequestHandler for improved type handling.83class LegacyRequestHandler : public BaseRequestHandler {84  using BaseRequestHandler::BaseRequestHandler;85  virtual void operator()(const llvm::json::Object &request) const = 0;86  void operator()(const protocol::Request &request) const override {87    auto req = toJSON(request);88    (*this)(*req.getAsObject());89  }90};91 92template <typename Args>93llvm::Expected<Args> parseArgs(const protocol::Request &request) {94  if (!is_optional_v<Args> && !request.arguments)95    return llvm::make_error<DAPError>(96        llvm::formatv("arguments required for command '{0}' "97                      "but none received",98                      request.command)99            .str());100 101  Args arguments;102  llvm::json::Path::Root root("arguments");103  if (request.arguments && !fromJSON(*request.arguments, arguments, root)) {104    std::string parse_failure;105    llvm::raw_string_ostream OS(parse_failure);106    OS << "invalid arguments for request '" << request.command107       << "': " << llvm::toString(root.getError()) << "\n";108    root.printErrorContext(*request.arguments, OS);109    return llvm::make_error<DAPError>(parse_failure);110  }111 112  return arguments;113}114template <>115inline llvm::Expected<protocol::EmptyArguments>116parseArgs(const protocol::Request &request) {117  return std::nullopt;118}119 120/// Base class for handling DAP requests. Handlers should declare their121/// arguments and response body types like:122///123/// class MyRequestHandler : public RequestHandler<Arguments, Response> {124///   ....125/// };126template <typename Args, typename Resp>127class RequestHandler : public BaseRequestHandler {128  using BaseRequestHandler::BaseRequestHandler;129 130  void operator()(const protocol::Request &request) const override {131    protocol::Response response;132    response.request_seq = request.seq;133    response.command = request.command;134 135    llvm::Expected<Args> arguments = parseArgs<Args>(request);136    if (llvm::Error err = arguments.takeError()) {137      HandleErrorResponse(std::move(err), response);138      dap.Send(response);139      return;140    }141 142    if constexpr (std::is_same_v<Resp, llvm::Error>) {143      if (llvm::Error err = Run(*arguments)) {144        HandleErrorResponse(std::move(err), response);145      } else {146        response.success = true;147      }148    } else {149      Resp body = Run(*arguments);150      if (llvm::Error err = body.takeError()) {151        HandleErrorResponse(std::move(err), response);152      } else {153        response.success = true;154        response.body = std::move(*body);155      }156    }157 158    // Mark the request as 'cancelled' if the debugger was interrupted while159    // evaluating this handler.160    if (dap.debugger.InterruptRequested()) {161      dap.debugger.CancelInterruptRequest();162      response.success = false;163      response.message = protocol::eResponseMessageCancelled;164      response.body = std::nullopt;165    }166 167    dap.Send(response);168 169    PostRun();170  };171 172  virtual Resp Run(const Args &) const = 0;173 174  /// A hook for a request handler to run additional operations after the175  /// request response is sent but before the next request handler.176  ///177  /// *NOTE*: PostRun will be invoked even if the `Run` operation returned an178  /// error.179  virtual void PostRun() const {};180 181  void HandleErrorResponse(llvm::Error err,182                           protocol::Response &response) const {183    response.success = false;184    llvm::handleAllErrors(185        std::move(err),186        [&](const NotStoppedError &err) {187          response.message = lldb_dap::protocol::eResponseMessageNotStopped;188        },189        [&](const DAPError &err) {190          protocol::ErrorMessage error_message;191          error_message.sendTelemetry = false;192          error_message.format = err.getMessage();193          error_message.showUser = err.getShowUser();194          error_message.id = err.convertToErrorCode().value();195          error_message.url = err.getURL();196          error_message.urlLabel = err.getURLLabel();197          protocol::ErrorResponseBody body;198          body.error = error_message;199          response.body = body;200        },201        [&](const llvm::ErrorInfoBase &err) {202          protocol::ErrorMessage error_message;203          error_message.showUser = true;204          error_message.sendTelemetry = false;205          error_message.format = err.message();206          error_message.id = err.convertToErrorCode().value();207          protocol::ErrorResponseBody body;208          body.error = error_message;209          response.body = body;210        });211  }212};213 214class AttachRequestHandler215    : public RequestHandler<protocol::AttachRequestArguments,216                            protocol::AttachResponse> {217public:218  using RequestHandler::RequestHandler;219  static llvm::StringLiteral GetCommand() { return "attach"; }220  llvm::Error Run(const protocol::AttachRequestArguments &args) const override;221  void PostRun() const override;222};223 224class BreakpointLocationsRequestHandler225    : public RequestHandler<226          protocol::BreakpointLocationsArguments,227          llvm::Expected<protocol::BreakpointLocationsResponseBody>> {228public:229  using RequestHandler::RequestHandler;230  static llvm::StringLiteral GetCommand() { return "breakpointLocations"; }231  FeatureSet GetSupportedFeatures() const override {232    return {protocol::eAdapterFeatureBreakpointLocationsRequest};233  }234  llvm::Expected<protocol::BreakpointLocationsResponseBody>235  Run(const protocol::BreakpointLocationsArguments &args) const override;236 237  std::vector<std::pair<uint32_t, uint32_t>>238  GetSourceBreakpointLocations(std::string path, uint32_t start_line,239                               uint32_t start_column, uint32_t end_line,240                               uint32_t end_column) const;241  std::vector<std::pair<uint32_t, uint32_t>>242  GetAssemblyBreakpointLocations(int64_t source_reference, uint32_t start_line,243                                 uint32_t end_line) const;244};245 246class CompletionsRequestHandler247    : public RequestHandler<protocol::CompletionsArguments,248                            llvm::Expected<protocol::CompletionsResponseBody>> {249public:250  using RequestHandler::RequestHandler;251  static llvm::StringLiteral GetCommand() { return "completions"; }252  FeatureSet GetSupportedFeatures() const override {253    return {protocol::eAdapterFeatureCompletionsRequest};254  }255  llvm::Expected<protocol::CompletionsResponseBody>256  Run(const protocol::CompletionsArguments &args) const override;257};258 259class ContinueRequestHandler260    : public RequestHandler<protocol::ContinueArguments,261                            llvm::Expected<protocol::ContinueResponseBody>> {262public:263  using RequestHandler::RequestHandler;264  static llvm::StringLiteral GetCommand() { return "continue"; }265  llvm::Expected<protocol::ContinueResponseBody>266  Run(const protocol::ContinueArguments &args) const override;267};268 269class ConfigurationDoneRequestHandler270    : public RequestHandler<protocol::ConfigurationDoneArguments,271                            protocol::ConfigurationDoneResponse> {272public:273  using RequestHandler::RequestHandler;274  static llvm::StringLiteral GetCommand() { return "configurationDone"; }275  FeatureSet GetSupportedFeatures() const override {276    return {protocol::eAdapterFeatureConfigurationDoneRequest};277  }278  protocol::ConfigurationDoneResponse279  Run(const protocol::ConfigurationDoneArguments &) const override;280};281 282class DisconnectRequestHandler283    : public RequestHandler<std::optional<protocol::DisconnectArguments>,284                            protocol::DisconnectResponse> {285public:286  using RequestHandler::RequestHandler;287  static llvm::StringLiteral GetCommand() { return "disconnect"; }288  FeatureSet GetSupportedFeatures() const override {289    return {protocol::eAdapterFeatureTerminateDebuggee};290  }291  llvm::Error292  Run(const std::optional<protocol::DisconnectArguments> &args) const override;293};294 295class EvaluateRequestHandler296    : public RequestHandler<protocol::EvaluateArguments,297                            llvm::Expected<protocol::EvaluateResponseBody>> {298public:299  using RequestHandler::RequestHandler;300  static llvm::StringLiteral GetCommand() { return "evaluate"; }301  llvm::Expected<protocol::EvaluateResponseBody>302  Run(const protocol::EvaluateArguments &) const override;303  FeatureSet GetSupportedFeatures() const override {304    return {protocol::eAdapterFeatureEvaluateForHovers};305  }306};307 308class ExceptionInfoRequestHandler final309    : public RequestHandler<310          protocol::ExceptionInfoArguments,311          llvm::Expected<protocol::ExceptionInfoResponseBody>> {312public:313  using RequestHandler::RequestHandler;314  static llvm::StringLiteral GetCommand() { return "exceptionInfo"; }315  FeatureSet GetSupportedFeatures() const override {316    return {protocol::eAdapterFeatureExceptionInfoRequest};317  }318  llvm::Expected<protocol::ExceptionInfoResponseBody>319  Run(const protocol::ExceptionInfoArguments &args) const override;320};321 322class InitializeRequestHandler323    : public RequestHandler<protocol::InitializeRequestArguments,324                            llvm::Expected<protocol::InitializeResponse>> {325public:326  using RequestHandler::RequestHandler;327  static llvm::StringLiteral GetCommand() { return "initialize"; }328  llvm::Expected<protocol::InitializeResponse>329  Run(const protocol::InitializeRequestArguments &args) const override;330};331 332class LaunchRequestHandler333    : public RequestHandler<protocol::LaunchRequestArguments,334                            protocol::LaunchResponse> {335public:336  using RequestHandler::RequestHandler;337  static llvm::StringLiteral GetCommand() { return "launch"; }338  llvm::Error339  Run(const protocol::LaunchRequestArguments &arguments) const override;340  void PostRun() const override;341};342 343class RestartRequestHandler : public LegacyRequestHandler {344public:345  using LegacyRequestHandler::LegacyRequestHandler;346  static llvm::StringLiteral GetCommand() { return "restart"; }347  void operator()(const llvm::json::Object &request) const override;348};349 350class NextRequestHandler351    : public RequestHandler<protocol::NextArguments, protocol::NextResponse> {352public:353  using RequestHandler::RequestHandler;354  static llvm::StringLiteral GetCommand() { return "next"; }355  llvm::Error Run(const protocol::NextArguments &args) const override;356};357 358class StepInRequestHandler : public RequestHandler<protocol::StepInArguments,359                                                   protocol::StepInResponse> {360public:361  using RequestHandler::RequestHandler;362  static llvm::StringLiteral GetCommand() { return "stepIn"; }363  llvm::Error Run(const protocol::StepInArguments &args) const override;364};365 366class StepInTargetsRequestHandler367    : public RequestHandler<368          protocol::StepInTargetsArguments,369          llvm::Expected<protocol::StepInTargetsResponseBody>> {370public:371  using RequestHandler::RequestHandler;372  static llvm::StringLiteral GetCommand() { return "stepInTargets"; }373  llvm::Expected<protocol::StepInTargetsResponseBody>374  Run(const protocol::StepInTargetsArguments &args) const override;375};376 377class StepOutRequestHandler : public RequestHandler<protocol::StepOutArguments,378                                                    protocol::StepOutResponse> {379public:380  using RequestHandler::RequestHandler;381  static llvm::StringLiteral GetCommand() { return "stepOut"; }382  llvm::Error Run(const protocol::StepOutArguments &args) const override;383};384 385class SetBreakpointsRequestHandler386    : public RequestHandler<387          protocol::SetBreakpointsArguments,388          llvm::Expected<protocol::SetBreakpointsResponseBody>> {389public:390  using RequestHandler::RequestHandler;391  static llvm::StringLiteral GetCommand() { return "setBreakpoints"; }392  FeatureSet GetSupportedFeatures() const override {393    return {protocol::eAdapterFeatureConditionalBreakpoints,394            protocol::eAdapterFeatureHitConditionalBreakpoints};395  }396  llvm::Expected<protocol::SetBreakpointsResponseBody>397  Run(const protocol::SetBreakpointsArguments &args) const override;398};399 400class SetExceptionBreakpointsRequestHandler401    : public RequestHandler<402          protocol::SetExceptionBreakpointsArguments,403          llvm::Expected<protocol::SetExceptionBreakpointsResponseBody>> {404public:405  using RequestHandler::RequestHandler;406  static llvm::StringLiteral GetCommand() { return "setExceptionBreakpoints"; }407  FeatureSet GetSupportedFeatures() const override {408    /// Prefer the `filterOptions` feature over the `exceptionOptions`.409    /// exceptionOptions is not supported in VSCode, while `filterOptions` is410    /// supported.411    return {protocol::eAdapterFeatureExceptionFilterOptions};412  }413  llvm::Expected<protocol::SetExceptionBreakpointsResponseBody>414  Run(const protocol::SetExceptionBreakpointsArguments &args) const override;415};416 417class SetFunctionBreakpointsRequestHandler418    : public RequestHandler<419          protocol::SetFunctionBreakpointsArguments,420          llvm::Expected<protocol::SetFunctionBreakpointsResponseBody>> {421public:422  using RequestHandler::RequestHandler;423  static llvm::StringLiteral GetCommand() { return "setFunctionBreakpoints"; }424  FeatureSet GetSupportedFeatures() const override {425    return {protocol::eAdapterFeatureFunctionBreakpoints};426  }427  llvm::Expected<protocol::SetFunctionBreakpointsResponseBody>428  Run(const protocol::SetFunctionBreakpointsArguments &args) const override;429};430 431class DataBreakpointInfoRequestHandler432    : public RequestHandler<433          protocol::DataBreakpointInfoArguments,434          llvm::Expected<protocol::DataBreakpointInfoResponseBody>> {435public:436  using RequestHandler::RequestHandler;437  static llvm::StringLiteral GetCommand() { return "dataBreakpointInfo"; }438  FeatureSet GetSupportedFeatures() const override {439    return {protocol::eAdapterFeatureDataBreakpointBytes};440  }441  llvm::Expected<protocol::DataBreakpointInfoResponseBody>442  Run(const protocol::DataBreakpointInfoArguments &args) const override;443};444 445class SetDataBreakpointsRequestHandler446    : public RequestHandler<447          protocol::SetDataBreakpointsArguments,448          llvm::Expected<protocol::SetDataBreakpointsResponseBody>> {449public:450  using RequestHandler::RequestHandler;451  static llvm::StringLiteral GetCommand() { return "setDataBreakpoints"; }452  FeatureSet GetSupportedFeatures() const override {453    return {protocol::eAdapterFeatureDataBreakpoints};454  }455  llvm::Expected<protocol::SetDataBreakpointsResponseBody>456  Run(const protocol::SetDataBreakpointsArguments &args) const override;457};458 459class SetInstructionBreakpointsRequestHandler460    : public RequestHandler<461          protocol::SetInstructionBreakpointsArguments,462          llvm::Expected<protocol::SetInstructionBreakpointsResponseBody>> {463public:464  using RequestHandler::RequestHandler;465  static llvm::StringLiteral GetCommand() {466    return "setInstructionBreakpoints";467  }468  FeatureSet GetSupportedFeatures() const override {469    return {protocol::eAdapterFeatureInstructionBreakpoints};470  }471  llvm::Expected<protocol::SetInstructionBreakpointsResponseBody>472  Run(const protocol::SetInstructionBreakpointsArguments &args) const override;473};474 475class CompileUnitsRequestHandler : public LegacyRequestHandler {476public:477  using LegacyRequestHandler::LegacyRequestHandler;478  static llvm::StringLiteral GetCommand() { return "compileUnits"; }479  void operator()(const llvm::json::Object &request) const override;480};481 482class ModulesRequestHandler final483    : public RequestHandler<std::optional<protocol::ModulesArguments>,484                            llvm::Expected<protocol::ModulesResponseBody>> {485public:486  using RequestHandler::RequestHandler;487  static llvm::StringLiteral GetCommand() { return "modules"; }488  FeatureSet GetSupportedFeatures() const override {489    return {protocol::eAdapterFeatureModulesRequest};490  }491  llvm::Expected<protocol::ModulesResponseBody>492  Run(const std::optional<protocol::ModulesArguments> &args) const override;493};494 495class PauseRequestHandler : public LegacyRequestHandler {496public:497  using LegacyRequestHandler::LegacyRequestHandler;498  static llvm::StringLiteral GetCommand() { return "pause"; }499  void operator()(const llvm::json::Object &request) const override;500};501 502class ScopesRequestHandler final503    : public RequestHandler<protocol::ScopesArguments,504                            llvm::Expected<protocol::ScopesResponseBody>> {505public:506  using RequestHandler::RequestHandler;507  static llvm::StringLiteral GetCommand() { return "scopes"; }508 509  llvm::Expected<protocol::ScopesResponseBody>510  Run(const protocol::ScopesArguments &args) const override;511};512 513class SetVariableRequestHandler final514    : public RequestHandler<protocol::SetVariableArguments,515                            llvm::Expected<protocol::SetVariableResponseBody>> {516public:517  using RequestHandler::RequestHandler;518  static llvm::StringLiteral GetCommand() { return "setVariable"; }519  FeatureSet GetSupportedFeatures() const override {520    return {protocol::eAdapterFeatureSetVariable};521  }522  llvm::Expected<protocol::SetVariableResponseBody>523  Run(const protocol::SetVariableArguments &args) const override;524};525 526class SourceRequestHandler final527    : public RequestHandler<protocol::SourceArguments,528                            llvm::Expected<protocol::SourceResponseBody>> {529public:530  using RequestHandler::RequestHandler;531  static llvm::StringLiteral GetCommand() { return "source"; }532  llvm::Expected<protocol::SourceResponseBody>533  Run(const protocol::SourceArguments &args) const override;534};535 536class StackTraceRequestHandler : public LegacyRequestHandler {537public:538  using LegacyRequestHandler::LegacyRequestHandler;539  static llvm::StringLiteral GetCommand() { return "stackTrace"; }540  void operator()(const llvm::json::Object &request) const override;541  FeatureSet GetSupportedFeatures() const override {542    return {protocol::eAdapterFeatureDelayedStackTraceLoading};543  }544};545 546class ThreadsRequestHandler547    : public RequestHandler<protocol::ThreadsArguments,548                            llvm::Expected<protocol::ThreadsResponseBody>> {549public:550  using RequestHandler::RequestHandler;551  static llvm::StringLiteral GetCommand() { return "threads"; }552  llvm::Expected<protocol::ThreadsResponseBody>553  Run(const protocol::ThreadsArguments &) const override;554};555 556class VariablesRequestHandler557    : public RequestHandler<protocol::VariablesArguments,558                            llvm::Expected<protocol::VariablesResponseBody>> {559public:560  using RequestHandler::RequestHandler;561  static llvm::StringLiteral GetCommand() { return "variables"; }562  llvm::Expected<protocol::VariablesResponseBody>563  Run(const protocol::VariablesArguments &) const override;564};565 566class LocationsRequestHandler : public LegacyRequestHandler {567public:568  using LegacyRequestHandler::LegacyRequestHandler;569  static llvm::StringLiteral GetCommand() { return "locations"; }570  void operator()(const llvm::json::Object &request) const override;571};572 573class DisassembleRequestHandler final574    : public RequestHandler<protocol::DisassembleArguments,575                            llvm::Expected<protocol::DisassembleResponseBody>> {576public:577  using RequestHandler::RequestHandler;578  static llvm::StringLiteral GetCommand() { return "disassemble"; }579  FeatureSet GetSupportedFeatures() const override {580    return {protocol::eAdapterFeatureDisassembleRequest};581  }582  llvm::Expected<protocol::DisassembleResponseBody>583  Run(const protocol::DisassembleArguments &args) const override;584};585 586class ReadMemoryRequestHandler final587    : public RequestHandler<protocol::ReadMemoryArguments,588                            llvm::Expected<protocol::ReadMemoryResponseBody>> {589public:590  using RequestHandler::RequestHandler;591  static llvm::StringLiteral GetCommand() { return "readMemory"; }592  FeatureSet GetSupportedFeatures() const override {593    return {protocol::eAdapterFeatureReadMemoryRequest};594  }595  llvm::Expected<protocol::ReadMemoryResponseBody>596  Run(const protocol::ReadMemoryArguments &args) const override;597};598 599class CancelRequestHandler : public RequestHandler<protocol::CancelArguments,600                                                   protocol::CancelResponse> {601public:602  using RequestHandler::RequestHandler;603  static llvm::StringLiteral GetCommand() { return "cancel"; }604  FeatureSet GetSupportedFeatures() const override {605    return {protocol::eAdapterFeatureCancelRequest};606  }607  llvm::Error Run(const protocol::CancelArguments &args) const override;608};609 610class ModuleSymbolsRequestHandler611    : public RequestHandler<612          protocol::ModuleSymbolsArguments,613          llvm::Expected<protocol::ModuleSymbolsResponseBody>> {614public:615  using RequestHandler::RequestHandler;616  static llvm::StringLiteral GetCommand() { return "__lldb_moduleSymbols"; }617  FeatureSet GetSupportedFeatures() const override {618    return {protocol::eAdapterFeatureSupportsModuleSymbolsRequest};619  }620  llvm::Expected<protocol::ModuleSymbolsResponseBody>621  Run(const protocol::ModuleSymbolsArguments &args) const override;622};623 624/// A request used in testing to get the details on all breakpoints that are625/// currently set in the target. This helps us to test "setBreakpoints" and626/// "setFunctionBreakpoints" requests to verify we have the correct set of627/// breakpoints currently set in LLDB.628class TestGetTargetBreakpointsRequestHandler : public LegacyRequestHandler {629public:630  using LegacyRequestHandler::LegacyRequestHandler;631  static llvm::StringLiteral GetCommand() {632    return "_testGetTargetBreakpoints";633  }634  void operator()(const llvm::json::Object &request) const override;635};636 637class WriteMemoryRequestHandler final638    : public RequestHandler<protocol::WriteMemoryArguments,639                            llvm::Expected<protocol::WriteMemoryResponseBody>> {640public:641  using RequestHandler::RequestHandler;642  static llvm::StringLiteral GetCommand() { return "writeMemory"; }643  FeatureSet GetSupportedFeatures() const override {644    return {protocol::eAdapterFeatureWriteMemoryRequest};645  }646  llvm::Expected<protocol::WriteMemoryResponseBody>647  Run(const protocol::WriteMemoryArguments &args) const override;648};649 650} // namespace lldb_dap651 652#endif653