Repository: llvm/llvm-project
Pull request #129919: [lldb][lldb-dap] Return optional from json utils
Author: login: da-viper
Labels: name: lldb
name: lldb-dap
Created: 2025-03-05T19:36:47Z | Merged: 2025-03-14T17:17:18Z

Completion of #129818 

Did not want to put `llvm::StringRef()` as the default value instead it was `""`


Diff:
diff --git a/lldb/tools/lldb-dap/BreakpointBase.cpp b/lldb/tools/lldb-dap/BreakpointBase.cpp
index 1e28c29082a9f..7979bac098766 100644
--- a/lldb/tools/lldb-dap/BreakpointBase.cpp
+++ b/lldb/tools/lldb-dap/BreakpointBase.cpp
@@ -13,8 +13,8 @@
 using namespace lldb_dap;
 
 BreakpointBase::BreakpointBase(DAP &d, const llvm::json::Object &obj)
-    : dap(d), condition(std::string(GetString(obj, "condition"))),
-      hitCondition(std::string(GetString(obj, "hitCondition"))) {}
+    : dap(d), condition(std::string(GetString(obj, "condition").value_or(""))),
+      hitCondition(std::string(GetString(obj, "hitCondition").value_or(""))) {}
 
 void BreakpointBase::UpdateBreakpoint(const BreakpointBase &request_bp) {
   if (condition != request_bp.condition) {
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index 4080e2c211035..2a8fe8e24c242 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -630,9 +630,11 @@ DAP::CreateTargetFromArguments(const llvm::json::Object &arguments,
   // enough information to determine correct arch and platform (or ELF can be
   // omitted at all), so it is good to leave the user an apportunity to specify
   // those. Any of those three can be left empty.
-  llvm::StringRef target_triple = GetString(arguments, "targetTriple");
-  llvm::StringRef platform_name = GetString(arguments, "platformName");
-  llvm::StringRef program = GetString(arguments, "program");
+  const llvm::StringRef target_triple =
+      GetString(arguments, "targetTriple").value_or("");
+  const llvm::StringRef platform_name =
+      GetString(arguments, "platformName").value_or("");
+  const llvm::StringRef program = GetString(arguments, "program").value_or("");
   auto target = this->debugger.CreateTarget(
       program.data(), target_triple.data(), platform_name.data(),
       true, // Add dependent modules.
@@ -668,7 +670,7 @@ bool DAP::HandleObject(const protocol::Message &M) {
   llvm::json::Object object = *v.getAsObject();
   const auto packet_type = GetString(object, "type");
   if (packet_type == "request") {
-    const auto command = GetString(object, "command");
+    const auto command = GetString(object, "command").value_or("");
 
     auto new_handler_pos = request_handlers.find(command);
     if (new_handler_pos != request_handlers.end()) {
@@ -704,7 +706,7 @@ bool DAP::HandleObject(const protocol::Message &M) {
         Result = std::move(*B);
       (*response_handler)(Result);
     } else {
-      llvm::StringRef message = GetString(object, "message");
+      llvm::StringRef message = GetString(object, "message").value_or("");
       if (message.empty()) {
         message = "Unknown error, response failed";
       }
diff --git a/lldb/tools/lldb-dap/FunctionBreakpoint.cpp b/lldb/tools/lldb-dap/FunctionBreakpoint.cpp
index f266d751833c7..cafae32b662f2 100644
--- a/lldb/tools/lldb-dap/FunctionBreakpoint.cpp
+++ b/lldb/tools/lldb-dap/FunctionBreakpoint.cpp
@@ -13,7 +13,8 @@
 namespace lldb_dap {
 
 FunctionBreakpoint::FunctionBreakpoint(DAP &d, const llvm::json::Object &obj)
-    : Breakpoint(d, obj), functionName(std::string(GetString(obj, "name"))) {}
+    : Breakpoint(d, obj),
+      functionName(std::string(GetString(obj, "name").value_or(""))) {}
 
 void FunctionBreakpoint::SetBreakpoint() {
   if (functionName.empty())
diff --git a/lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp
index 8f42f5b96b937..20f7c80a1ed90 100644
--- a/lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp
@@ -58,7 +58,7 @@ void AttachRequestHandler::operator()(const llvm::json::Object &request) const {
   const auto gdb_remote_port =
       GetInteger<uint64_t>(arguments, "gdb-remote-port").value_or(invalid_port);
   const auto gdb_remote_hostname =
-      GetString(arguments, "gdb-remote-hostname", "localhost");
+      GetString(arguments, "gdb-remote-hostname").value_or("localhost");
   if (pid != LLDB_INVALID_PROCESS_ID)
     attach_info.SetProcessID(pid);
   const auto wait_for = GetBoolean(arguments, "waitFor").value_or(false);
@@ -69,23 +69,25 @@ void AttachRequestHandler::operator()(const llvm::json::Object &request) const {
   dap.exit_commands = GetStrings(arguments, "exitCommands");
   dap.terminate_commands = GetStrings(arguments, "terminateCommands");
   auto attachCommands = GetStrings(arguments, "attachCommands");
-  llvm::StringRef core_file = GetString(arguments, "coreFile");
-  const auto timeout_seconds =
+  llvm::StringRef core_file = GetString(arguments, "coreFile").value_or("");
+  const uint64_t timeout_seconds =
       GetInteger<uint64_t>(arguments, "timeout").value_or(30);
   dap.stop_at_entry = core_file.empty()
                           ? GetBoolean(arguments, "stopOnEntry").value_or(false)
                           : true;
   dap.post_run_commands = GetStrings(arguments, "postRunCommands");
-  const llvm::StringRef debuggerRoot = GetString(arguments, "debuggerRoot");
+  const llvm::StringRef debuggerRoot =
+      GetString(arguments, "debuggerRoot").value_or("");
   dap.enable_auto_variable_summaries =
       GetBoolean(arguments, "enableAutoVariableSummaries").value_or(false);
   dap.enable_synthetic_child_debugging =
       GetBoolean(arguments, "enableSyntheticChildDebugging").value_or(false);
   dap.display_extended_backtrace =
       GetBoolean(arguments, "displayExtendedBacktrace").value_or(false);
-  dap.command_escape_prefix = GetString(arguments, "commandEscapePrefix", "`");
-  dap.SetFrameFormat(GetString(arguments, "customFrameFormat"));
-  dap.SetThreadFormat(GetString(arguments, "customThreadFormat"));
+  dap.command_escape_prefix =
+      GetString(arguments, "commandEscapePrefix").value_or("`");
+  dap.SetFrameFormat(GetString(arguments, "customFrameFormat").value_or(""));
+  dap.SetThreadFormat(GetString(arguments, "customThreadFormat").value_or(""));
 
   PrintWelcomeMessage();
 
diff --git a/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp b/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp
index d6efd659ae8e0..022baf77458d0 100644
--- a/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp
@@ -130,7 +130,7 @@ void BreakpointLocationsRequestHandler::operator()(
   FillResponse(request, response);
   auto *arguments = request.getObject("arguments");
   auto *source = arguments->getObject("source");
-  std::string path = GetString(source, "path").str();
+  std::string path = GetString(source, "path").value_or("").str();
   const auto start_line = GetInteger<uint64_t>(arguments, "line")
                               .value_or(LLDB_INVALID_LINE_NUMBER);
   const auto start_column = GetInteger<uint64_t>(arguments, "column")
diff --git a/lldb/tools/lldb-dap/Handler/CompileUnitsRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/CompileUnitsRequestHandler.cpp
index 51ae44a0def9d..cd937116f7380 100644
--- a/lldb/tools/lldb-dap/Handler/CompileUnitsRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/CompileUnitsRequestHandler.cpp
@@ -60,7 +60,8 @@ void CompileUnitsRequestHandler::operator()(
   llvm::json::Object body;
   llvm::json::Array units;
   const auto *arguments = request.getObject("arguments");
-  std::string module_id = std::string(GetString(arguments, "moduleId"));
+  const std::string module_id =
+      GetString(arguments, "moduleId").value_or("").str();
   int num_modules = dap.target.GetNumModules();
   for (int i = 0; i < num_modules; i++) {
     auto curr_module = dap.target.GetModuleAtIndex(i);
diff --git a/lldb/tools/lldb-dap/Handler/CompletionsHandler.cpp b/lldb/tools/lldb-dap/Handler/CompletionsHandler.cpp
index bfe2e734ecff6..5414aaeb2c317 100644
--- a/lldb/tools/lldb-dap/Handler/CompletionsHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/CompletionsHandler.cpp
@@ -142,7 +142,7 @@ void CompletionsRequestHandler::operator()(
     frame.GetThread().SetSelectedFrame(frame.GetFrameID());
   }
 
-  std::string text = GetString(arguments, "text").str();
+  std::string text = GetString(arguments, "text").value_or("").str();
   auto original_column =
       GetInteger<int64_t>(arguments, "column").value_or(text.size());
   auto original_line = GetInteger<int64_t>(arguments, "line").value_or(1);
diff --git a/lldb/tools/lldb-dap/Handler/DataBreakpointInfoRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/DataBreakpointInfoRequestHandler.cpp
index 7443db18331c5..4d920f8556254 100644
--- a/lldb/tools/lldb-dap/Handler/DataBreakpointInfoRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/DataBreakpointInfoRequestHandler.cpp
@@ -117,7 +117,7 @@ void DataBreakpointInfoRequestHandler::operator()(
   const auto *arguments = request.getObject("arguments");
   const auto variablesReference =
       GetInteger<uint64_t>(arguments, "variablesReference").value_or(0);
-  llvm::StringRef name = GetString(arguments, "name");
+  llvm::StringRef name = GetString(arguments, "name").value_or("");
   lldb::SBFrame frame = dap.GetLLDBFrame(*arguments);
   lldb::SBValue variable = dap.variables.FindVariable(variablesReference, name);
   std::string addr, size;
diff --git a/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp
index 56502baf6d283..f0cb7be70210d 100644
--- a/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp
@@ -93,7 +93,8 @@ void DisassembleRequestHandler::operator()(
   FillResponse(request, response);
   auto *arguments = request.getObject("arguments");
 
-  llvm::StringRef memoryReference = GetString(arguments, "memoryReference");
+  llvm::StringRef memoryReference =
+      GetString(arguments, "memoryReference").value_or("");
   auto addr_opt = DecodeMemoryReference(memoryReference);
   if (!addr_opt.has_value()) {
     response["success"] = false;
diff --git a/lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp
index 36a9d9bff5db9..e9f08a1017abc 100644
--- a/lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp
@@ -145,8 +145,9 @@ void EvaluateRequestHandler::operator()(
   llvm::json::Object body;
   const auto *arguments = request.getObject("arguments");
   lldb::SBFrame frame = dap.GetLLDBFrame(*arguments);
-  std::string expression = GetString(arguments, "expression").str();
-  llvm::StringRef context = GetString(arguments, "context");
+  std::string expression =
+      GetString(arguments, "expression").value_or("").str();
+  const llvm::StringRef context = GetString(arguments, "context").value_or("");
   bool repeat_last_command =
       expression.empty() && dap.last_nonempty_var_expression.empty();
 
diff --git a/lldb/tools/lldb-dap/Handler/LaunchRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/LaunchRequestHandler.cpp
index 9fa1ddd4e848c..f64c186376a36 100644
--- a/lldb/tools/lldb-dap/Handler/LaunchRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/LaunchRequestHandler.cpp
@@ -61,16 +61,18 @@ void LaunchRequestHandler::operator()(const llvm::json::Object &request) const {
   dap.terminate_commands = GetStrings(arguments, "terminateCommands");
   dap.post_run_commands = GetStrings(arguments, "postRunCommands");
   dap.stop_at_entry = GetBoolean(arguments, "stopOnEntry").value_or(false);
-  const llvm::StringRef debuggerRoot = GetString(arguments, "debuggerRoot");
+  const llvm::StringRef debuggerRoot =
+      GetString(arguments, "debuggerRoot").value_or("");
   dap.enable_auto_variable_summaries =
       GetBoolean(arguments, "enableAutoVariableSummaries").value_or(false);
   dap.enable_synthetic_child_debugging =
       GetBoolean(arguments, "enableSyntheticChildDebugging").value_or(false);
   dap.display_extended_backtrace =
       GetBoolean(arguments, "displayExtendedBacktrace").value_or(false);
-  dap.command_escape_prefix = GetString(arguments, "commandEscapePrefix", "`");
-  dap.SetFrameFormat(GetString(arguments, "customFrameFormat"));
-  dap.SetThreadFormat(GetString(arguments, "customThreadFormat"));
+  dap.command_escape_prefix =
+      GetString(arguments, "commandEscapePrefix").value_or("`");
+  dap.SetFrameFormat(GetString(arguments, "customFrameFormat").value_or(""));
+  dap.SetThreadFormat(GetString(arguments, "customThreadFormat").value_or(""));
 
   PrintWelcomeMessage();
 
diff --git a/lldb/tools/lldb-dap/Handler/ReadMemoryRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/ReadMemoryRequestHandler.cpp
index 919aecd9c68dd..891c2af4f2f28 100644
--- a/lldb/tools/lldb-dap/Handler/ReadMemoryRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/ReadMemoryRequestHandler.cpp
@@ -98,7 +98,8 @@ void ReadMemoryRequestHandler::operator()(
   FillResponse(request, response);
   auto *arguments = request.getObject("arguments");
 
-  llvm::StringRef memoryReference = GetString(arguments, "memoryReference");
+  llvm::StringRef memoryReference =
+      GetString(arguments, "memoryReference").value_or("");
   auto addr_opt = DecodeMemoryReference(memoryReference);
   if (!addr_opt.has_value()) {
     response["success"] = false;
diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
index e43fa36d25e3f..2e661329edea1 100644
--- a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
@@ -54,7 +54,7 @@ void RequestHandler::SetSourceMapFromArguments(
   std::string sourceMapCommand;
   llvm::raw_string_ostream strm(sourceMapCommand);
   strm << "settings set target.source-map ";
-  const auto sourcePath = GetString(arguments, "sourcePath");
+  const auto sourcePath = GetString(arguments, "sourcePath").value_or("");
 
   // sourceMap is the new, more general form of sourcePath and overrides it.
   constexpr llvm::StringRef sourceMapKey = "sourceMap";
@@ -169,7 +169,7 @@ RequestHandler::LaunchProcess(const llvm::json::Object &request) const {
 
   // Grab the current working directory if there is one and set it in the
   // launch info.
-  const auto cwd = GetString(arguments, "cwd");
+  const auto cwd = GetString(arguments, "cwd").value_or("");
   if (!cwd.empty())
     launch_info.SetWorkingDirectory(cwd.data());
 
diff --git a/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
index 413db38733ffa..5ca2c9c01965e 100644
--- a/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
@@ -130,7 +130,7 @@ void SetBreakpointsRequestHandler::operator()(
   FillResponse(request, response);
   const auto *arguments = request.getObject("arguments");
   const auto *source = arguments->getObject("source");
-  const auto path = GetString(source, "path");
+  const auto path = GetString(source, "path").value_or("");
   const auto *breakpoints = arguments->getArray("breakpoints");
   llvm::json::Array response_breakpoints;
 
diff --git a/lldb/tools/lldb-dap/Handler/SetVariableRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/SetVariableRequestHandler.cpp
index 7d2f13f0a327e..3ab1bb32fd18e 100644
--- a/lldb/tools/lldb-dap/Handler/SetVariableRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/SetVariableRequestHandler.cpp
@@ -116,9 +116,9 @@ void SetVariableRequestHandler::operator()(
   // This is a reference to the containing variable/scope
   const auto variablesReference =
       GetInteger<uint64_t>(arguments, "variablesReference").value_or(0);
-  llvm::StringRef name = GetString(arguments, "name");
+  llvm::StringRef name = GetString(arguments, "name").value_or("");
 
-  const auto value = GetString(arguments, "value");
+  const auto value = GetString(arguments, "value").value_or("");
   // Set success to false just in case we don't find the variable by name
   response.try_emplace("success", false);
 
diff --git a/lldb/tools/lldb-dap/InstructionBreakpoint.cpp b/lldb/tools/lldb-dap/InstructionBreakpoint.cpp
index a008b633c165b..710787625ec58 100644
--- a/lldb/tools/lldb-dap/InstructionBreakpoint.cpp
+++ b/lldb/tools/lldb-dap/InstructionBreakpoint.cpp
@@ -22,6 +22,7 @@ InstructionBreakpoint::InstructionBreakpoint(DAP &d,
     : Breakpoint(d, obj), instructionAddressReference(LLDB_INVALID_ADDRESS),
       offset(GetInteger<int64_t>(obj, "offset").value_or(0)) {
   GetString(obj, "instructionReference")
+      .value_or("")
       .getAsInteger(0, instructionAddressReference);
   instructionAddressReference += offset;
 }
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp
index 932145b1799bd..795c73805eef3 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -70,34 +70,17 @@ llvm::StringRef GetAsString(const llvm::json::Value &value) {
 }
 
 // Gets a string from a JSON object using the key, or returns an empty string.
-llvm::StringRef GetString(const llvm::json::Object &obj, llvm::StringRef key,
-                          llvm::StringRef defaultValue) {
-  if (std::optional<llvm::StringRef> value = obj.getString(key))
-    return *value;
-  return defaultValue;
+std::optional<llvm::StringRef> GetString(const llvm::json::Object &obj,
+                                         llvm::StringRef key) {
+  return obj.getString(key);
 }
 
-llvm::StringRef GetString(const llvm::json::Object *obj, llvm::StringRef key,
-                          llvm::StringRef defaultValue) {
+std::optional<llvm::StringRef> GetString(const llvm::json::Object *obj,
+                                         llvm::StringRef key) {
   if (obj == nullptr)
-    return defaultValue;
-  return GetString(*obj, key, defaultValue);
-}
-
-// Gets an unsigned integer from a JSON object using the key, or returns the
-// specified fail value.
-uint64_t GetUnsigned(const llvm::json::Object &obj, llvm::StringRef key,
-                     uint64_t fail_value) {
-  if (auto value = obj.getInteger(key))
-    return (uint64_t)*value;
-  return fail_value;
-}
+    return std::nullopt;
 
-uint64_t GetUnsigned(const llvm::json::Object *obj, llvm::StringRef key,
-                     uint64_t fail_value) {
-  if (obj == nullptr)
-    return fail_value;
-  return GetUnsigned(*obj, key, fail_value);
+  return GetString(*obj, key);
 }
 
 std::optional<bool> GetBoolean(const llvm::json::Object &obj,
@@ -116,6 +99,19 @@ std::optional<bool> GetBoolean(const llvm::json::Object *obj,
   return std::nullopt;
 }
 
+std::optional<int64_t> GetSigned(const llvm::json::Object &obj,
+                                 llvm::StringRef key) {
+  return obj.getInteger(key);
+}
+
+std::optional<int64_t> GetSigned(const llvm::json::Object *obj,
+                                 llvm::StringRef key) {
+  if (obj == nullptr)
+    return std::nullopt;
+
+  return GetSigned(*obj, key);
+}
+
 bool ObjectContainsKey(const llvm::json::Object &obj, llvm::StringRef key) {
   return obj.find(key) != obj.end();
 }
@@ -265,8 +261,9 @@ void FillResponse(const llvm::json::Object &request,
   // to true by default.
   response.try_emplace("type", "response");
   response.try_emplace("seq", (int64_t)0);
-  EmplaceSafeString(response, "command", GetString(request, "command"));
-  const auto seq = GetInteger<int64_t>(request, "seq").value_or(0);
+  EmplaceSafeString(response, "command",
+                    GetString(request, "command").value_or(""));
+  const int64_t seq = GetSigned(request, "seq").value_or(0);
   response.try_emplace("request_seq", seq);
   response.try_emplace("success", true);
 }
@@ -1439,13 +1436,14 @@ CreateRunInTerminalReverseRequest(const llvm::json::Object &launch_request,
     args.push_back(std::to_string(debugger_pid));
   }
   args.push_back("--launch-target");
-  args.push_back(GetString(launch_request_arguments, "program").str());
+  args.push_back(
+      GetString(launch_request_arguments, "program").value_or("").str());
   std::vector<std::string> target_args =
       GetStrings(launch_request_arguments, "args");
   args.insert(args.end(), target_args.begin(), target_args.end());
   run_in_terminal_args.try_emplace("args", args);
 
-  const auto cwd = GetString(launch_request_arguments, "cwd");
+  const auto cwd = GetString(launch_request_arguments, "cwd").value_or("");
   if (!cwd.empty())
     run_in_terminal_args.try_emplace("cwd", cwd);
 
diff --git a/lldb/tools/lldb-dap/JSONUtils.h b/lldb/tools/lldb-dap/JSONUtils.h
index 17d4b850eb78a..a8858020f7d85 100644
--- a/lldb/tools/lldb-dap/JSONUtils.h
+++ b/lldb/tools/lldb-dap/JSONUtils.h
@@ -62,17 +62,14 @@ llvm::StringRef GetAsString(const llvm::json::Value &value);
 /// \param[in] key
 ///     The key to use when extracting the value
 ///
-/// \param[in] defaultValue
-///     The default value to return if the key is not present
-///
 /// \return
 ///     A llvm::StringRef that contains the string value for the
-///     specified \a key, or the default value if there is no key that
+///     specified \a key, or \a std::nullopt if there is no key that
 ///     matches or if the value is not a string.
-llvm::StringRef GetString(const llvm::json::Object &obj, llvm::StringRef key,
-                          llvm::StringRef defaultValue = {});
-llvm::StringRef GetString(const llvm::json::Object *obj, llvm::StringRef key,
-                          llvm::StringRef defaultValue = {});
+std::optional<llvm::StringRef> GetString(const llvm::json::Object &obj,
+                                         llvm::StringRef key);
+std::optional<llvm::StringRef> GetString(const llvm::json::Object *obj,
+                                         llvm::StringRef key);
 
 /// Extract the integer value for the specified key from the specified object
 /// and return it as the specified integer type T.
diff --git a/lldb/tools/lldb-dap/SourceBreakpoint.cpp b/lldb/tools/lldb-dap/SourceBreakpoint.cpp
index 7742dce2928b5..4c6b36119c84f 100644
--- a/lldb/tools/lldb-dap/SourceBreakpoint.cpp
+++ b/lldb/tools/lldb-dap/SourceBreakpoint.cpp
@@ -26,7 +26,7 @@ namespace lldb_dap {
 
 SourceBreakpoint::SourceBreakpoint(DAP &dap, const llvm::json::Object &obj)
     : Breakpoint(dap, obj),
-      logMessage(std::string(GetString(obj, "logMessage"))),
+      logMessage(GetString(obj, "logMessage").value_or("").str()),
       line(
           GetInteger<uint64_t>(obj, "line").value_or(LLDB_INVALID_LINE_NUMBER)),
       column(GetInteger<uint64_t>(obj, "column")
diff --git a/lldb/tools/lldb-dap/Watchpoint.cpp b/lldb/tools/lldb-dap/Watchpoint.cpp
index 0e68a35877c66..8681057c8d3f2 100644
--- a/lldb/tools/lldb-dap/Watchpoint.cpp
+++ b/lldb/tools/lldb-dap/Watchpoint.cpp
@@ -20,8 +20,8 @@
 namespace lldb_dap {
 Watchpoint::Watchpoint(DAP &d, const llvm::json::Object &obj)
     : BreakpointBase(d, obj) {
-  llvm::StringRef dataId = GetString(obj, "dataId");
-  std::string accessType = GetString(obj, "accessType").str();
+  llvm::StringRef dataId = GetString(obj, "dataId").value_or("");
+  std::string accessType = GetString(obj, "accessType").value_or("").str();
   auto [addr_str, size_str] = dataId.split('/');
   llvm::to_integer(addr_str, addr, 16);
   llvm::to_integer(size_str, size);


Reviews:
user: login: walter-erquinigo
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-07T23:12:07Z
user: login: da-viper
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-09T21:48:46Z
user: login: walter-erquinigo
body: all good then!
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-13T17:23:01Z

Review comments:
diff_hunk: @@ -13,8 +13,8 @@
 using namespace lldb_dap;
 
 BreakpointBase::BreakpointBase(DAP &d, const llvm::json::Object &obj)
-    : dap(d), condition(std::string(GetString(obj, "condition"))),
-      hitCondition(std::string(GetString(obj, "hitCondition"))) {}
+    : dap(d), condition(std::string(GetString(obj, "condition").value_or(""))),
path: lldb/tools/lldb-dap/BreakpointBase.cpp
user: login: walter-erquinigo
body: I think that instead of `""` you should use `{}`, which would create an empty StringRef without an actual string being backed by it. That is closer to the original source code.
I don't think why `""` would break with your patch, but if there's a place that does `GetString().GetData() == nullptr`, then there would be some divergence. So I'd rather play safe.
created_at: 2025-03-07T23:12:04Z
author_association: MEMBER
diff_hunk: @@ -13,8 +13,8 @@
 using namespace lldb_dap;
 
 BreakpointBase::BreakpointBase(DAP &d, const llvm::json::Object &obj)
-    : dap(d), condition(std::string(GetString(obj, "condition"))),
-      hitCondition(std::string(GetString(obj, "hitCondition"))) {}
+    : dap(d), condition(std::string(GetString(obj, "condition").value_or(""))),
path: lldb/tools/lldb-dap/BreakpointBase.cpp
user: login: da-viper
body: I did try that before, but I doesn't work because at the position the compiler sees it as an initializer list. and `llvm::StringRef` does not have an initializer-list constructor. 

in the previous fuction 
`GetString(..... llvm::StringRef default_value = { } )` here it is treated as llvm::StringRef{} and can infer it.   


created_at: 2025-03-09T21:48:46Z
author_association: CONTRIBUTOR

PR comments:
user: login: llvmbot
created_at: 2025-03-05T19:37:25Z
body: 
<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: None (Da-Viper)

<details>
<summary>Changes</summary>

Completion of #<!-- -->129818 

Did not want to put `llvm::StringRef()` as the default value instead it was `""`

---

Patch is 34.46 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/129919.diff


25 Files Affected:

- (modified) lldb/tools/lldb-dap/BreakpointBase.cpp (+2-2) 
- (modified) lldb/tools/lldb-dap/DAP.cpp (+12-9) 
- (modified) lldb/tools/lldb-dap/FunctionBreakpoint.cpp (+2-1) 
- (modified) lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp (+12-9) 
- (modified) lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp (+8-6) 
- (modified) lldb/tools/lldb-dap/Handler/CompileUnitsRequestHandler.cpp (+2-1) 
- (modified) lldb/tools/lldb-dap/Handler/CompletionsHandler.cpp (+4-3) 
- (modified) lldb/tools/lldb-dap/Handler/DataBreakpointInfoRequestHandler.cpp (+2-2) 
- (modified) lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp (+5-3) 
- (modified) lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp (+3-2) 
- (modified) lldb/tools/lldb-dap/Handler/LaunchRequestHandler.cpp (+6-4) 
- (modified) lldb/tools/lldb-dap/Handler/LocationsRequestHandler.cpp (+2-1) 
- (modified) lldb/tools/lldb-dap/Handler/ReadMemoryRequestHandler.cpp (+4-3) 
- (modified) lldb/tools/lldb-dap/Handler/RequestHandler.cpp (+4-3) 
- (modified) lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp (+1-1) 
- (modified) lldb/tools/lldb-dap/Handler/SetVariableRequestHandler.cpp (+4-4) 
- (modified) lldb/tools/lldb-dap/Handler/SourceRequestHandler.cpp (+3-2) 
- (modified) lldb/tools/lldb-dap/Handler/StackTraceRequestHandler.cpp (+2-2) 
- (modified) lldb/tools/lldb-dap/Handler/StepInRequestHandler.cpp (+1-1) 
- (modified) lldb/tools/lldb-dap/Handler/VariablesRequestHandler.cpp (+3-3) 
- (modified) lldb/tools/lldb-dap/InstructionBreakpoint.cpp (+2-1) 
- (modified) lldb/tools/lldb-dap/JSONUtils.cpp (+30-31) 
- (modified) lldb/tools/lldb-dap/JSONUtils.h (+16-19) 
- (modified) lldb/tools/lldb-dap/SourceBreakpoint.cpp (+3-3) 
- (modified) lldb/tools/lldb-dap/Watchpoint.cpp (+2-2) 


``````````diff
diff --git a/lldb/tools/lldb-dap/BreakpointBase.cpp b/lldb/tools/lldb-dap/BreakpointBase.cpp
index 1e28c29082a9f..7979bac098766 100644
--- a/lldb/tools/lldb-dap/BreakpointBase.cpp
+++ b/lldb/tools/lldb-dap/BreakpointBase.cpp
@@ -13,8 +13,8 @@
 using namespace lldb_dap;
 
 BreakpointBase::BreakpointBase(DAP &d, const llvm::json::Object &obj)
-    : dap(d), condition(std::string(GetString(obj, "condition"))),
-      hitCondition(std::string(GetString(obj, "hitCondition"))) {}
+    : dap(d), condition(std::string(GetString(obj, "condition").value_or(""))),
+      hitCondition(std::string(GetString(obj, "hitCondition").value_or(""))) {}
 
 void BreakpointBase::UpdateBreakpoint(const BreakpointBase &request_bp) {
   if (condition != request_bp.condition) {
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index c4790414f64f9..435cd0f188d75 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -526,12 +526,13 @@ ExceptionBreakpoint *DAP::GetExceptionBPFromStopReason(lldb::SBThread &thread) {
 }
 
 lldb::SBThread DAP::GetLLDBThread(const llvm::json::Object &arguments) {
-  auto tid = GetSigned(arguments, "threadId", LLDB_INVALID_THREAD_ID);
+  auto tid = GetSigned(arguments, "threadId").value_or(LLDB_INVALID_THREAD_ID);
   return target.GetProcess().GetThreadByID(tid);
 }
 
 lldb::SBFrame DAP::GetLLDBFrame(const llvm::json::Object &arguments) {
-  const uint64_t frame_id = GetUnsigned(arguments, "frameId", UINT64_MAX);
+  const uint64_t frame_id =
+      GetUnsigned(arguments, "frameId").value_or(UINT64_MAX);
   lldb::SBProcess process = target.GetProcess();
   // Upper 32 bits is the thread index ID
   lldb::SBThread thread =
@@ -688,9 +689,11 @@ DAP::CreateTargetFromArguments(const llvm::json::Object &arguments,
   // enough information to determine correct arch and platform (or ELF can be
   // omitted at all), so it is good to leave the user an apportunity to specify
   // those. Any of those three can be left empty.
-  llvm::StringRef target_triple = GetString(arguments, "targetTriple");
-  llvm::StringRef platform_name = GetString(arguments, "platformName");
-  llvm::StringRef program = GetString(arguments, "program");
+  const llvm::StringRef target_triple =
+      GetString(arguments, "targetTriple").value_or("");
+  const llvm::StringRef platform_name =
+      GetString(arguments, "platformName").value_or("");
+  const llvm::StringRef program = GetString(arguments, "program").value_or("");
   auto target = this->debugger.CreateTarget(
       program.data(), target_triple.data(), platform_name.data(),
       true, // Add dependent modules.
@@ -754,9 +757,9 @@ PacketStatus DAP::GetNextObject(llvm::json::Object &object) {
 }
 
 bool DAP::HandleObject(const llvm::json::Object &object) {
-  const auto packet_type = GetString(object, "type");
+  const auto packet_type = GetString(object, "type").value_or("");
   if (packet_type == "request") {
-    const auto command = GetString(object, "command");
+    const auto command = GetString(object, "command").value_or("");
 
     auto new_handler_pos = request_handlers.find(command);
     if (new_handler_pos != request_handlers.end()) {
@@ -771,7 +774,7 @@ bool DAP::HandleObject(const llvm::json::Object &object) {
   }
 
   if (packet_type == "response") {
-    auto id = GetSigned(object, "request_seq", 0);
+    auto id = GetSigned(object, "request_seq").value_or(0);
 
     std::unique_ptr<ResponseHandler> response_handler;
     {
@@ -794,7 +797,7 @@ bool DAP::HandleObject(const llvm::json::Object &object) {
       }
       (*response_handler)(Result);
     } else {
-      llvm::StringRef message = GetString(object, "message");
+      llvm::StringRef message = GetString(object, "message").value_or("");
       if (message.empty()) {
         message = "Unknown error, response failed";
       }
diff --git a/lldb/tools/lldb-dap/FunctionBreakpoint.cpp b/lldb/tools/lldb-dap/FunctionBreakpoint.cpp
index f266d751833c7..cafae32b662f2 100644
--- a/lldb/tools/lldb-dap/FunctionBreakpoint.cpp
+++ b/lldb/tools/lldb-dap/FunctionBreakpoint.cpp
@@ -13,7 +13,8 @@
 namespace lldb_dap {
 
 FunctionBreakpoint::FunctionBreakpoint(DAP &d, const llvm::json::Object &obj)
-    : Breakpoint(d, obj), functionName(std::string(GetString(obj, "name"))) {}
+    : Breakpoint(d, obj),
+      functionName(std::string(GetString(obj, "name").value_or(""))) {}
 
 void FunctionBreakpoint::SetBreakpoint() {
   if (functionName.empty())
diff --git a/lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp
index 2733f58b74683..5d45dc4fe0b34 100644
--- a/lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp
@@ -54,11 +54,11 @@ void AttachRequestHandler::operator()(const llvm::json::Object &request) const {
   const int invalid_port = 0;
   const auto *arguments = request.getObject("arguments");
   const lldb::pid_t pid =
-      GetUnsigned(arguments, "pid", LLDB_INVALID_PROCESS_ID);
+      GetUnsigned(arguments, "pid").value_or(LLDB_INVALID_PROCESS_ID);
   const auto gdb_remote_port =
-      GetUnsigned(arguments, "gdb-remote-port", invalid_port);
+      GetUnsigned(arguments, "gdb-remote-port").value_or(invalid_port);
   const auto gdb_remote_hostname =
-      GetString(arguments, "gdb-remote-hostname", "localhost");
+      GetString(arguments, "gdb-remote-hostname").value_or("localhost");
   if (pid != LLDB_INVALID_PROCESS_ID)
     attach_info.SetProcessID(pid);
   const auto wait_for = GetBoolean(arguments, "waitFor").value_or(false);
@@ -69,22 +69,25 @@ void AttachRequestHandler::operator()(const llvm::json::Object &request) const {
   dap.exit_commands = GetStrings(arguments, "exitCommands");
   dap.terminate_commands = GetStrings(arguments, "terminateCommands");
   auto attachCommands = GetStrings(arguments, "attachCommands");
-  llvm::StringRef core_file = GetString(arguments, "coreFile");
-  const uint64_t timeout_seconds = GetUnsigned(arguments, "timeout", 30);
+  llvm::StringRef core_file = GetString(arguments, "coreFile").value_or("");
+  const uint64_t timeout_seconds =
+      GetUnsigned(arguments, "timeout").value_or(30);
   dap.stop_at_entry = core_file.empty()
                           ? GetBoolean(arguments, "stopOnEntry").value_or(false)
                           : true;
   dap.post_run_commands = GetStrings(arguments, "postRunCommands");
-  const llvm::StringRef debuggerRoot = GetString(arguments, "debuggerRoot");
+  const llvm::StringRef debuggerRoot =
+      GetString(arguments, "debuggerRoot").value_or("");
   dap.enable_auto_variable_summaries =
       GetBoolean(arguments, "enableAutoVariableSummaries").value_or(false);
   dap.enable_synthetic_child_debugging =
       GetBoolean(arguments, "enableSyntheticChildDebugging").value_or(false);
   dap.display_extended_backtrace =
       GetBoolean(arguments, "displayExtendedBacktrace").value_or(false);
-  dap.command_escape_prefix = GetString(arguments, "commandEscapePrefix", "`");
-  dap.SetFrameFormat(GetString(arguments, "customFrameFormat"));
-  dap.SetThreadFormat(GetString(arguments, "customThreadFormat"));
+  dap.command_escape_prefix =
+      GetString(arguments, "commandEscapePrefix").value_or("`");
+  dap.SetFrameFormat(GetString(arguments, "customFrameFormat").value_or(""));
+  dap.SetThreadFormat(GetString(arguments, "customThreadFormat").value_or(""));
 
   PrintWelcomeMessage();
 
diff --git a/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp b/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp
index 1b5c8ba307dcb..66195fd5fb5bd 100644
--- a/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp
@@ -130,12 +130,14 @@ void BreakpointLocationsRequestHandler::operator()(
   FillResponse(request, response);
   auto *arguments = request.getObject("arguments");
   auto *source = arguments->getObject("source");
-  std::string path = GetString(source, "path").str();
-  uint64_t start_line = GetUnsigned(arguments, "line", 0);
-  uint64_t start_column = GetUnsigned(arguments, "column", 0);
-  uint64_t end_line = GetUnsigned(arguments, "endLine", start_line);
-  uint64_t end_column =
-      GetUnsigned(arguments, "endColumn", std::numeric_limits<uint64_t>::max());
+  std::string path = GetString(source, "path").value_or("").str();
+  const uint64_t start_line = GetUnsigned(arguments, "line").value_or(0);
+  const uint64_t start_column = GetUnsigned(arguments, "column").value_or(0);
+  const uint64_t end_line =
+      GetUnsigned(arguments, "endLine").value_or(start_line);
+  const uint64_t end_column =
+      GetUnsigned(arguments, "endColumn")
+          .value_or(std::numeric_limits<uint64_t>::max());
 
   lldb::SBFileSpec file_spec(path.c_str(), true);
   lldb::SBSymbolContextList compile_units =
diff --git a/lldb/tools/lldb-dap/Handler/CompileUnitsRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/CompileUnitsRequestHandler.cpp
index 51ae44a0def9d..cd937116f7380 100644
--- a/lldb/tools/lldb-dap/Handler/CompileUnitsRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/CompileUnitsRequestHandler.cpp
@@ -60,7 +60,8 @@ void CompileUnitsRequestHandler::operator()(
   llvm::json::Object body;
   llvm::json::Array units;
   const auto *arguments = request.getObject("arguments");
-  std::string module_id = std::string(GetString(arguments, "moduleId"));
+  const std::string module_id =
+      GetString(arguments, "moduleId").value_or("").str();
   int num_modules = dap.target.GetNumModules();
   for (int i = 0; i < num_modules; i++) {
     auto curr_module = dap.target.GetModuleAtIndex(i);
diff --git a/lldb/tools/lldb-dap/Handler/CompletionsHandler.cpp b/lldb/tools/lldb-dap/Handler/CompletionsHandler.cpp
index 09b73054ca62f..96d573c48513c 100644
--- a/lldb/tools/lldb-dap/Handler/CompletionsHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/CompletionsHandler.cpp
@@ -142,9 +142,10 @@ void CompletionsRequestHandler::operator()(
     frame.GetThread().SetSelectedFrame(frame.GetFrameID());
   }
 
-  std::string text = GetString(arguments, "text").str();
-  auto original_column = GetSigned(arguments, "column", text.size());
-  auto original_line = GetSigned(arguments, "line", 1);
+  std::string text = GetString(arguments, "text").value_or("").str();
+  const auto original_column =
+      GetSigned(arguments, "column").value_or(text.size());
+  const auto original_line = GetSigned(arguments, "line").value_or(1);
   auto offset = original_column - 1;
   if (original_line > 1) {
     llvm::SmallVector<::llvm::StringRef, 2> lines;
diff --git a/lldb/tools/lldb-dap/Handler/DataBreakpointInfoRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/DataBreakpointInfoRequestHandler.cpp
index 64829b93c783d..2926ede0c3f7a 100644
--- a/lldb/tools/lldb-dap/Handler/DataBreakpointInfoRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/DataBreakpointInfoRequestHandler.cpp
@@ -116,8 +116,8 @@ void DataBreakpointInfoRequestHandler::operator()(
   llvm::json::Array accessTypes{"read", "write", "readWrite"};
   const auto *arguments = request.getObject("arguments");
   const auto variablesReference =
-      GetUnsigned(arguments, "variablesReference", 0);
-  llvm::StringRef name = GetString(arguments, "name");
+      GetUnsigned(arguments, "variablesReference").value_or(0);
+  const llvm::StringRef name = GetString(arguments, "name").value_or("");
   lldb::SBFrame frame = dap.GetLLDBFrame(*arguments);
   lldb::SBValue variable = dap.variables.FindVariable(variablesReference, name);
   std::string addr, size;
diff --git a/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp
index d6ff2a7fd8880..f401b52d2c5dd 100644
--- a/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp
@@ -93,7 +93,8 @@ void DisassembleRequestHandler::operator()(
   FillResponse(request, response);
   auto *arguments = request.getObject("arguments");
 
-  llvm::StringRef memoryReference = GetString(arguments, "memoryReference");
+  llvm::StringRef memoryReference =
+      GetString(arguments, "memoryReference").value_or("");
   auto addr_opt = DecodeMemoryReference(memoryReference);
   if (!addr_opt.has_value()) {
     response["success"] = false;
@@ -104,7 +105,7 @@ void DisassembleRequestHandler::operator()(
   }
   lldb::addr_t addr_ptr = *addr_opt;
 
-  addr_ptr += GetSigned(arguments, "instructionOffset", 0);
+  addr_ptr += GetSigned(arguments, "instructionOffset").value_or(0);
   lldb::SBAddress addr(addr_ptr, dap.target);
   if (!addr.IsValid()) {
     response["success"] = false;
@@ -113,7 +114,8 @@ void DisassembleRequestHandler::operator()(
     return;
   }
 
-  const auto inst_count = GetUnsigned(arguments, "instructionCount", 0);
+  const auto inst_count =
+      GetUnsigned(arguments, "instructionCount").value_or(0);
   lldb::SBInstructionList insts = dap.target.ReadInstructions(addr, inst_count);
 
   if (!insts.IsValid()) {
diff --git a/lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp
index 36a9d9bff5db9..e9f08a1017abc 100644
--- a/lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp
@@ -145,8 +145,9 @@ void EvaluateRequestHandler::operator()(
   llvm::json::Object body;
   const auto *arguments = request.getObject("arguments");
   lldb::SBFrame frame = dap.GetLLDBFrame(*arguments);
-  std::string expression = GetString(arguments, "expression").str();
-  llvm::StringRef context = GetString(arguments, "context");
+  std::string expression =
+      GetString(arguments, "expression").value_or("").str();
+  const llvm::StringRef context = GetString(arguments, "context").value_or("");
   bool repeat_last_command =
       expression.empty() && dap.last_nonempty_var_expression.empty();
 
diff --git a/lldb/tools/lldb-dap/Handler/LaunchRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/LaunchRequestHandler.cpp
index 9fa1ddd4e848c..f64c186376a36 100644
--- a/lldb/tools/lldb-dap/Handler/LaunchRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/LaunchRequestHandler.cpp
@@ -61,16 +61,18 @@ void LaunchRequestHandler::operator()(const llvm::json::Object &request) const {
   dap.terminate_commands = GetStrings(arguments, "terminateCommands");
   dap.post_run_commands = GetStrings(arguments, "postRunCommands");
   dap.stop_at_entry = GetBoolean(arguments, "stopOnEntry").value_or(false);
-  const llvm::StringRef debuggerRoot = GetString(arguments, "debuggerRoot");
+  const llvm::StringRef debuggerRoot =
+      GetString(arguments, "debuggerRoot").value_or("");
   dap.enable_auto_variable_summaries =
       GetBoolean(arguments, "enableAutoVariableSummaries").value_or(false);
   dap.enable_synthetic_child_debugging =
       GetBoolean(arguments, "enableSyntheticChildDebugging").value_or(false);
   dap.display_extended_backtrace =
       GetBoolean(arguments, "displayExtendedBacktrace").value_or(false);
-  dap.command_escape_prefix = GetString(arguments, "commandEscapePrefix", "`");
-  dap.SetFrameFormat(GetString(arguments, "customFrameFormat"));
-  dap.SetThreadFormat(GetString(arguments, "customThreadFormat"));
+  dap.command_escape_prefix =
+      GetString(arguments, "commandEscapePrefix").value_or("`");
+  dap.SetFrameFormat(GetString(arguments, "customFrameFormat").value_or(""));
+  dap.SetThreadFormat(GetString(arguments, "customThreadFormat").value_or(""));
 
   PrintWelcomeMessage();
 
diff --git a/lldb/tools/lldb-dap/Handler/LocationsRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/LocationsRequestHandler.cpp
index fa763f3ffe931..3a2fecf350b9b 100644
--- a/lldb/tools/lldb-dap/Handler/LocationsRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/LocationsRequestHandler.cpp
@@ -97,7 +97,8 @@ void LocationsRequestHandler::operator()(
   FillResponse(request, response);
   auto *arguments = request.getObject("arguments");
 
-  uint64_t location_id = GetUnsigned(arguments, "locationReference", 0);
+  uint64_t location_id =
+      GetUnsigned(arguments, "locationReference").value_or(0);
   // We use the lowest bit to distinguish between value location and declaration
   // location
   auto [var_ref, is_value_location] = UnpackLocation(location_id);
diff --git a/lldb/tools/lldb-dap/Handler/ReadMemoryRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/ReadMemoryRequestHandler.cpp
index bc8158f9d3079..590bcd69912f5 100644
--- a/lldb/tools/lldb-dap/Handler/ReadMemoryRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/ReadMemoryRequestHandler.cpp
@@ -98,7 +98,8 @@ void ReadMemoryRequestHandler::operator()(
   FillResponse(request, response);
   auto *arguments = request.getObject("arguments");
 
-  llvm::StringRef memoryReference = GetString(arguments, "memoryReference");
+  llvm::StringRef memoryReference =
+      GetString(arguments, "memoryReference").value_or("");
   auto addr_opt = DecodeMemoryReference(memoryReference);
   if (!addr_opt.has_value()) {
     response["success"] = false;
@@ -108,8 +109,8 @@ void ReadMemoryRequestHandler::operator()(
     return;
   }
   lldb::addr_t addr_int = *addr_opt;
-  addr_int += GetSigned(arguments, "offset", 0);
-  const uint64_t count_requested = GetUnsigned(arguments, "count", 0);
+  addr_int += GetSigned(arguments, "offset").value_or(0);
+  const uint64_t count_requested = GetUnsigned(arguments, "count").value_or(0);
 
   // We also need support reading 0 bytes
   // VS Code sends those requests to check if a `memoryReference`
diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
index d4030965869a1..c1450ce2fc687 100644
--- a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
@@ -42,7 +42,7 @@ void RequestHandler::SetSourceMapFromArguments(
   std::string sourceMapCommand;
   llvm::raw_string_ostream strm(sourceMapCommand);
   strm << "settings set target.source-map ";
-  const auto sourcePath = GetString(arguments, "sourcePath");
+  const auto sourcePath = GetString(arguments, "sourcePath").value_or("");
 
   // sourceMap is the new, more general form of sourcePath and overrides it.
   constexpr llvm::StringRef sourceMapKey = "sourceMap";
@@ -157,7 +157,7 @@ RequestHandler::LaunchProcess(const llvm::json::Object &request) const {
 
   // Grab the current working directory if there is one and set it in the
   // launch info.
-  const auto cwd = GetString(arguments, "cwd");
+  const auto cwd = GetString(arguments, "cwd").value_or("");
   if (!cwd.empty())
     launch_info.SetWorkingDirectory(cwd.data());
 
@@ -184,7 +184,8 @@ RequestHandler::LaunchProcess(const llvm::json::Object &request) const {
   launch_info.SetDetachOnError(detachOnError);
   launch_info.SetLaunchFlags(flags | lldb::eLaunchFlagDebug |
                              lldb::eLaunchFlagStopAtEntry);
-  const uint64_t timeout_seconds = GetUnsigned(arguments, "timeout", 30);
+  const uint64_t timeout_seconds =
+      GetUnsigned(arguments, "timeout").value_or(30);
 
   if (GetBoolean(arguments, "runInTerminal").value_or(false)) {
     if (llvm::Error err = RunInTerminal(dap, request, timeout_seconds))
diff --git a/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
index 413db38733ffa..5ca2c9c01965e 100644
--- a/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/SetBreakpointsRequestHandler.cpp
@@ -130,7 +130,7 @@ void SetBreakpointsRequestHandler::operator()(
   FillResponse(request, response);
   const auto *arguments = request.getObject("arguments");
   const auto *source = arguments->getObject("source");
-  const auto path = GetString(source, "path");
+  const auto path = GetString(source, "path").value_or("");
   const auto *breakpoints = arguments->getArray("breakpoints");
   llvm::json::Array response_breakpoints;
 
diff --git a/lldb/tools/lldb-dap/Handler/SetVariableRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/SetVariableRequestHandler.cpp
index 3a271bc1a1db5..6274100446dcc 100644
--- a/lldb/tools/lldb-dap/Handler/SetVariableRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/SetVariableRequestHandler.cpp
@@ -115,10 +115,10 @@ void SetVariableRequestHandler::operator()(
   const auto *arguments = request.getObject("arguments");
   // This is a reference to the con...
[truncated]

``````````

</details>

author_association: MEMBER
user: login: DavidSpickett
created_at: 2025-03-06T12:58:39Z
body: I read through this and all the usages look correct. I suppose there are some places that could use the optional without doing value_or, but changing those now would complicate the patch.

I'll leave it to @JDevlieghere to review fully since they did the previous part.
author_association: COLLABORATOR
user: login: JDevlieghere
created_at: 2025-03-06T17:05:55Z
body: The two commits that change `GetSigned` and `GetUnsigned` are no longer necessary after #129823. The commit that updates `GetString` looks fine. 

Thinking out loud: I see a handful of cases where we can check the optional (like should we pass "--launch-target" if there's no value). On the other hand, I think in the majority of cases, we don't really care about the value being empty or not set, but the new API is strictly more powerful. If we wanted to streamline the latter, we could have an overload with the empty string as the default value. If someone wants to specify anything else, they should use the `value_or` API. 
author_association: MEMBER