[Lldb-commits] [lldb] d5f5475 - Add SBDebugger::GetSetting() public APIs

Jeffrey Tan via lldb-commits lldb-commits at lists.llvm.org
Sun Sep 11 20:50:18 PDT 2022


Author: Jeffrey Tan
Date: 2022-09-11T20:50:03-07:00
New Revision: d5f54751048b59cc101125e03dabc57536fc1d2d

URL: https://github.com/llvm/llvm-project/commit/d5f54751048b59cc101125e03dabc57536fc1d2d
DIFF: https://github.com/llvm/llvm-project/commit/d5f54751048b59cc101125e03dabc57536fc1d2d.diff

LOG: Add SBDebugger::GetSetting() public APIs

This patch adds new SBDebugger::GetSetting() API which
enables client to access settings as SBStructedData.

Implementation wise, a new ToJSON() virtual function is added to OptionValue
class so that each concrete child class can override and provides its
own JSON representation. This patch aims to define the APIs and implement
a common set of OptionValue child classes, leaving the remaining for
future patches.

This patch is used later by auto deduce source map from source line breakpoint
feature for testing generated source map entries.

Differential Revision: https://reviews.llvm.org/D133038

Added: 
    

Modified: 
    lldb/bindings/interface/SBDebugger.i
    lldb/include/lldb/API/SBDebugger.h
    lldb/include/lldb/Core/UserSettingsController.h
    lldb/include/lldb/Interpreter/OptionValue.h
    lldb/include/lldb/Interpreter/OptionValueArray.h
    lldb/include/lldb/Interpreter/OptionValueBoolean.h
    lldb/include/lldb/Interpreter/OptionValueChar.h
    lldb/include/lldb/Interpreter/OptionValueDictionary.h
    lldb/include/lldb/Interpreter/OptionValueFileSpec.h
    lldb/include/lldb/Interpreter/OptionValueFormat.h
    lldb/include/lldb/Interpreter/OptionValueFormatEntity.h
    lldb/include/lldb/Interpreter/OptionValueLanguage.h
    lldb/include/lldb/Interpreter/OptionValuePathMappings.h
    lldb/include/lldb/Interpreter/OptionValueProperties.h
    lldb/include/lldb/Interpreter/OptionValueRegex.h
    lldb/include/lldb/Interpreter/OptionValueSInt64.h
    lldb/include/lldb/Interpreter/OptionValueString.h
    lldb/include/lldb/Interpreter/OptionValueUInt64.h
    lldb/include/lldb/Interpreter/OptionValueUUID.h
    lldb/include/lldb/Target/PathMappingList.h
    lldb/source/API/SBDebugger.cpp
    lldb/source/Core/UserSettingsController.cpp
    lldb/source/Interpreter/OptionValueArray.cpp
    lldb/source/Interpreter/OptionValueDictionary.cpp
    lldb/source/Interpreter/OptionValueFormat.cpp
    lldb/source/Interpreter/OptionValueFormatEntity.cpp
    lldb/source/Interpreter/OptionValueLanguage.cpp
    lldb/source/Interpreter/OptionValuePathMappings.cpp
    lldb/source/Interpreter/OptionValueProperties.cpp
    lldb/source/Target/PathMappingList.cpp
    lldb/test/API/commands/settings/TestSettings.py
    lldb/test/API/functionalities/source-map/TestTargetSourceMap.py

Removed: 
    


################################################################################
diff  --git a/lldb/bindings/interface/SBDebugger.i b/lldb/bindings/interface/SBDebugger.i
index 5d51a6ac20d2f..e82ce2aa8e7c7 100644
--- a/lldb/bindings/interface/SBDebugger.i
+++ b/lldb/bindings/interface/SBDebugger.i
@@ -225,6 +225,8 @@ public:
         }
     }
 
+    lldb::SBStructuredData GetSetting(const char *setting = nullptr);
+
     SBError
     SetInputString (const char* data);
 

diff  --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h
index b9a9b593d0ad4..d3de61caeb811 100644
--- a/lldb/include/lldb/API/SBDebugger.h
+++ b/lldb/include/lldb/API/SBDebugger.h
@@ -115,6 +115,21 @@ class LLDB_API SBDebugger {
 
   void Clear();
 
+  /// Getting a specific setting value into SBStructuredData format.
+  /// Client can specify empty string or null to get all settings.
+  ///
+  /// Example usages:
+  /// lldb::SBStructuredData settings = debugger.GetSetting();
+  /// lldb::SBStructuredData settings = debugger.GetSetting(nullptr);
+  /// lldb::SBStructuredData settings = debugger.GetSetting("");
+  /// lldb::SBStructuredData settings = debugger.GetSetting("target.arg0");
+  /// lldb::SBStructuredData settings = debugger.GetSetting("target");
+  ///
+  /// \param[out] setting
+  ///   Property setting path to retrieve values. e.g "target.source-map"
+  ///
+  lldb::SBStructuredData GetSetting(const char *setting = nullptr);
+
   void SetAsync(bool b);
 
   bool GetAsync();

diff  --git a/lldb/include/lldb/Core/UserSettingsController.h b/lldb/include/lldb/Core/UserSettingsController.h
index 35555f08c351d..8afef06359738 100644
--- a/lldb/include/lldb/Core/UserSettingsController.h
+++ b/lldb/include/lldb/Core/UserSettingsController.h
@@ -57,10 +57,11 @@ class Properties {
 
   virtual Status DumpPropertyValue(const ExecutionContext *exe_ctx,
                                    Stream &strm, llvm::StringRef property_path,
-                                   uint32_t dump_mask);
+                                   uint32_t dump_mask, bool is_json = false);
 
   virtual void DumpAllPropertyValues(const ExecutionContext *exe_ctx,
-                                     Stream &strm, uint32_t dump_mask);
+                                     Stream &strm, uint32_t dump_mask,
+                                     bool is_json = false);
 
   virtual void DumpAllDescriptions(CommandInterpreter &interpreter,
                                    Stream &strm) const;

diff  --git a/lldb/include/lldb/Interpreter/OptionValue.h b/lldb/include/lldb/Interpreter/OptionValue.h
index 277a5c9d30f05..3c842d1f5ce79 100644
--- a/lldb/include/lldb/Interpreter/OptionValue.h
+++ b/lldb/include/lldb/Interpreter/OptionValue.h
@@ -17,6 +17,7 @@
 #include "lldb/lldb-defines.h"
 #include "lldb/lldb-private-enumerations.h"
 #include "lldb/lldb-private-interfaces.h"
+#include "llvm/Support/JSON.h"
 
 namespace lldb_private {
 
@@ -82,6 +83,16 @@ class OptionValue {
   virtual void DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
                          uint32_t dump_mask) = 0;
 
+  // TODO: make this function pure virtual after implementing it in all
+  // child classes.
+  virtual llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) {
+    // Return nullptr which will create a llvm::json::Value() that is a NULL
+    // value. No setting should ever really have a NULL value in JSON. This
+    // indicates an error occurred and if/when we add a FromJSON() it will know
+    // to fail if someone tries to set it with a NULL JSON value.
+    return nullptr;
+  }
+
   virtual Status
   SetValueFromString(llvm::StringRef value,
                      VarSetOperationType op = eVarSetOperationAssign);

diff  --git a/lldb/include/lldb/Interpreter/OptionValueArray.h b/lldb/include/lldb/Interpreter/OptionValueArray.h
index af43887635e9b..147e15ef4335d 100644
--- a/lldb/include/lldb/Interpreter/OptionValueArray.h
+++ b/lldb/include/lldb/Interpreter/OptionValueArray.h
@@ -29,6 +29,8 @@ class OptionValueArray : public Cloneable<OptionValueArray, OptionValue> {
   void DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
                  uint32_t dump_mask) override;
 
+  llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override;
+
   Status
   SetValueFromString(llvm::StringRef value,
                      VarSetOperationType op = eVarSetOperationAssign) override;

diff  --git a/lldb/include/lldb/Interpreter/OptionValueBoolean.h b/lldb/include/lldb/Interpreter/OptionValueBoolean.h
index fd15ccb12c40b..01e7c6c09d8e8 100644
--- a/lldb/include/lldb/Interpreter/OptionValueBoolean.h
+++ b/lldb/include/lldb/Interpreter/OptionValueBoolean.h
@@ -29,6 +29,10 @@ class OptionValueBoolean : public Cloneable<OptionValueBoolean, OptionValue> {
   void DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
                  uint32_t dump_mask) override;
 
+  llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override {
+    return m_current_value;
+  }
+
   Status
   SetValueFromString(llvm::StringRef value,
                      VarSetOperationType op = eVarSetOperationAssign) override;

diff  --git a/lldb/include/lldb/Interpreter/OptionValueChar.h b/lldb/include/lldb/Interpreter/OptionValueChar.h
index 6b8a314a7c994..32ec2bb59fc55 100644
--- a/lldb/include/lldb/Interpreter/OptionValueChar.h
+++ b/lldb/include/lldb/Interpreter/OptionValueChar.h
@@ -30,6 +30,10 @@ class OptionValueChar : public Cloneable<OptionValueChar, OptionValue> {
   void DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
                  uint32_t dump_mask) override;
 
+  llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override {
+    return m_current_value;
+  }
+
   Status
   SetValueFromString(llvm::StringRef value,
                      VarSetOperationType op = eVarSetOperationAssign) override;

diff  --git a/lldb/include/lldb/Interpreter/OptionValueDictionary.h b/lldb/include/lldb/Interpreter/OptionValueDictionary.h
index 4c6bcaecd4c78..1fdccdeccef50 100644
--- a/lldb/include/lldb/Interpreter/OptionValueDictionary.h
+++ b/lldb/include/lldb/Interpreter/OptionValueDictionary.h
@@ -34,6 +34,8 @@ class OptionValueDictionary
   void DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
                  uint32_t dump_mask) override;
 
+  llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override;
+
   Status
   SetValueFromString(llvm::StringRef value,
                      VarSetOperationType op = eVarSetOperationAssign) override;

diff  --git a/lldb/include/lldb/Interpreter/OptionValueFileSpec.h b/lldb/include/lldb/Interpreter/OptionValueFileSpec.h
index 6648bbac93e33..b680a89688d97 100644
--- a/lldb/include/lldb/Interpreter/OptionValueFileSpec.h
+++ b/lldb/include/lldb/Interpreter/OptionValueFileSpec.h
@@ -35,6 +35,10 @@ class OptionValueFileSpec : public Cloneable<OptionValueFileSpec, OptionValue> {
   void DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
                  uint32_t dump_mask) override;
 
+  llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override {
+    return m_current_value.GetPath();
+  }
+
   Status
   SetValueFromString(llvm::StringRef value,
                      VarSetOperationType op = eVarSetOperationAssign) override;

diff  --git a/lldb/include/lldb/Interpreter/OptionValueFormat.h b/lldb/include/lldb/Interpreter/OptionValueFormat.h
index 1f2c66b164d55..5be885fe4f70d 100644
--- a/lldb/include/lldb/Interpreter/OptionValueFormat.h
+++ b/lldb/include/lldb/Interpreter/OptionValueFormat.h
@@ -31,6 +31,8 @@ class OptionValueFormat
   void DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
                  uint32_t dump_mask) override;
 
+  llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override;
+
   Status
   SetValueFromString(llvm::StringRef value,
                      VarSetOperationType op = eVarSetOperationAssign) override;

diff  --git a/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h b/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h
index cb8b2ef13fa46..b8ef03a44d033 100644
--- a/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h
+++ b/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h
@@ -28,6 +28,8 @@ class OptionValueFormatEntity
   void DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
                  uint32_t dump_mask) override;
 
+  llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override;
+
   Status
   SetValueFromString(llvm::StringRef value,
                      VarSetOperationType op = eVarSetOperationAssign) override;

diff  --git a/lldb/include/lldb/Interpreter/OptionValueLanguage.h b/lldb/include/lldb/Interpreter/OptionValueLanguage.h
index c00f71ffff335..f20a2c64f698d 100644
--- a/lldb/include/lldb/Interpreter/OptionValueLanguage.h
+++ b/lldb/include/lldb/Interpreter/OptionValueLanguage.h
@@ -33,6 +33,8 @@ class OptionValueLanguage : public Cloneable<OptionValueLanguage, OptionValue> {
   void DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
                  uint32_t dump_mask) override;
 
+  llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override;
+
   Status
   SetValueFromString(llvm::StringRef value,
                      VarSetOperationType op = eVarSetOperationAssign) override;

diff  --git a/lldb/include/lldb/Interpreter/OptionValuePathMappings.h b/lldb/include/lldb/Interpreter/OptionValuePathMappings.h
index 4bc65ce76c767..82a968a77c12e 100644
--- a/lldb/include/lldb/Interpreter/OptionValuePathMappings.h
+++ b/lldb/include/lldb/Interpreter/OptionValuePathMappings.h
@@ -29,6 +29,8 @@ class OptionValuePathMappings
   void DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
                  uint32_t dump_mask) override;
 
+  llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override;
+
   Status
   SetValueFromString(llvm::StringRef value,
                      VarSetOperationType op = eVarSetOperationAssign) override;

diff  --git a/lldb/include/lldb/Interpreter/OptionValueProperties.h b/lldb/include/lldb/Interpreter/OptionValueProperties.h
index 14f496bca6cdf..7c344dc23a0f8 100644
--- a/lldb/include/lldb/Interpreter/OptionValueProperties.h
+++ b/lldb/include/lldb/Interpreter/OptionValueProperties.h
@@ -47,11 +47,13 @@ class OptionValueProperties
   void DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
                  uint32_t dump_mask) override;
 
+  llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override;
+
   ConstString GetName() const override { return m_name; }
 
   virtual Status DumpPropertyValue(const ExecutionContext *exe_ctx,
                                    Stream &strm, llvm::StringRef property_path,
-                                   uint32_t dump_mask);
+                                   uint32_t dump_mask, bool is_json = false);
 
   virtual void DumpAllDescriptions(CommandInterpreter &interpreter,
                                    Stream &strm) const;

diff  --git a/lldb/include/lldb/Interpreter/OptionValueRegex.h b/lldb/include/lldb/Interpreter/OptionValueRegex.h
index 129987484f195..3c188003ceb23 100644
--- a/lldb/include/lldb/Interpreter/OptionValueRegex.h
+++ b/lldb/include/lldb/Interpreter/OptionValueRegex.h
@@ -28,6 +28,10 @@ class OptionValueRegex : public Cloneable<OptionValueRegex, OptionValue> {
   void DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
                  uint32_t dump_mask) override;
 
+  llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override {
+    return m_regex.GetText();
+  }
+
   Status
   SetValueFromString(llvm::StringRef value,
                      VarSetOperationType op = eVarSetOperationAssign) override;

diff  --git a/lldb/include/lldb/Interpreter/OptionValueSInt64.h b/lldb/include/lldb/Interpreter/OptionValueSInt64.h
index 3493eb1037c05..5efae627758ac 100644
--- a/lldb/include/lldb/Interpreter/OptionValueSInt64.h
+++ b/lldb/include/lldb/Interpreter/OptionValueSInt64.h
@@ -35,6 +35,10 @@ class OptionValueSInt64 : public Cloneable<OptionValueSInt64, OptionValue> {
   void DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
                  uint32_t dump_mask) override;
 
+  llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override {
+    return m_current_value;
+  }
+
   Status
   SetValueFromString(llvm::StringRef value,
                      VarSetOperationType op = eVarSetOperationAssign) override;

diff  --git a/lldb/include/lldb/Interpreter/OptionValueString.h b/lldb/include/lldb/Interpreter/OptionValueString.h
index 820656d19e2cb..becf35f8e88ef 100644
--- a/lldb/include/lldb/Interpreter/OptionValueString.h
+++ b/lldb/include/lldb/Interpreter/OptionValueString.h
@@ -69,6 +69,10 @@ class OptionValueString : public Cloneable<OptionValueString, OptionValue> {
   void DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
                  uint32_t dump_mask) override;
 
+  llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override {
+    return m_current_value;
+  }
+
   Status
   SetValueFromString(llvm::StringRef value,
                      VarSetOperationType op = eVarSetOperationAssign) override;
@@ -109,7 +113,7 @@ class OptionValueString : public Cloneable<OptionValueString, OptionValue> {
   bool IsCurrentValueEmpty() const { return m_current_value.empty(); }
 
   bool IsDefaultValueEmpty() const { return m_default_value.empty(); }
-  
+
   void SetValidator(ValidatorCallback validator, void *baton = nullptr) {
     m_validator = validator;
     m_validator_baton = baton;

diff  --git a/lldb/include/lldb/Interpreter/OptionValueUInt64.h b/lldb/include/lldb/Interpreter/OptionValueUInt64.h
index f212b2a19defd..30c27bf73d99c 100644
--- a/lldb/include/lldb/Interpreter/OptionValueUInt64.h
+++ b/lldb/include/lldb/Interpreter/OptionValueUInt64.h
@@ -38,6 +38,10 @@ class OptionValueUInt64 : public Cloneable<OptionValueUInt64, OptionValue> {
   void DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
                  uint32_t dump_mask) override;
 
+  llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override {
+    return m_current_value;
+  }
+
   Status
   SetValueFromString(llvm::StringRef value,
                      VarSetOperationType op = eVarSetOperationAssign) override;

diff  --git a/lldb/include/lldb/Interpreter/OptionValueUUID.h b/lldb/include/lldb/Interpreter/OptionValueUUID.h
index 0ed490d1811d6..e0e4235fdf076 100644
--- a/lldb/include/lldb/Interpreter/OptionValueUUID.h
+++ b/lldb/include/lldb/Interpreter/OptionValueUUID.h
@@ -29,6 +29,10 @@ class OptionValueUUID : public Cloneable<OptionValueUUID, OptionValue> {
   void DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
                  uint32_t dump_mask) override;
 
+  llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override {
+    return m_uuid.GetAsString();
+  }
+
   Status
   SetValueFromString(llvm::StringRef value,
                      VarSetOperationType op = eVarSetOperationAssign) override;

diff  --git a/lldb/include/lldb/Target/PathMappingList.h b/lldb/include/lldb/Target/PathMappingList.h
index f1cc779ea50fe..badbe3e0f8c63 100644
--- a/lldb/include/lldb/Target/PathMappingList.h
+++ b/lldb/include/lldb/Target/PathMappingList.h
@@ -9,10 +9,11 @@
 #ifndef LLDB_TARGET_PATHMAPPINGLIST_H
 #define LLDB_TARGET_PATHMAPPINGLIST_H
 
-#include <map>
-#include <vector>
 #include "lldb/Utility/ConstString.h"
 #include "lldb/Utility/Status.h"
+#include "llvm/Support/JSON.h"
+#include <map>
+#include <vector>
 
 namespace lldb_private {
 
@@ -41,6 +42,8 @@ class PathMappingList {
   // By default, dump all pairs.
   void Dump(Stream *s, int pair_index = -1);
 
+  llvm::json::Value ToJSON();
+
   bool IsEmpty() const { return m_pairs.empty(); }
 
   size_t GetSize() const { return m_pairs.size(); }

diff  --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp
index 0de934b2a9bd9..8a0c7d1b647d9 100644
--- a/lldb/source/API/SBDebugger.cpp
+++ b/lldb/source/API/SBDebugger.cpp
@@ -436,6 +436,29 @@ SBError SBDebugger::SetErrorFile(SBFile file) {
   return error;
 }
 
+lldb::SBStructuredData SBDebugger::GetSetting(const char *setting) {
+  LLDB_INSTRUMENT_VA(this, setting);
+
+  SBStructuredData data;
+  if (!m_opaque_sp)
+    return data;
+
+  StreamString json_strm;
+  ExecutionContext exe_ctx(
+      m_opaque_sp->GetCommandInterpreter().GetExecutionContext());
+  if (setting && strlen(setting) > 0)
+    m_opaque_sp->DumpPropertyValue(&exe_ctx, json_strm, setting,
+                                   /*dump_mask*/ 0,
+                                   /*is_json*/ true);
+  else
+    m_opaque_sp->DumpAllPropertyValues(&exe_ctx, json_strm, /*dump_mask*/ 0,
+                                       /*is_json*/ true);
+
+  data.m_impl_up->SetObjectSP(
+      StructuredData::ParseJSON(json_strm.GetString().str()));
+  return data;
+}
+
 FILE *SBDebugger::GetInputFileHandle() {
   LLDB_INSTRUMENT_VA(this);
   if (m_opaque_sp) {

diff  --git a/lldb/source/Core/UserSettingsController.cpp b/lldb/source/Core/UserSettingsController.cpp
index b9f7d5eaa6871..9ea4f78ddd062 100644
--- a/lldb/source/Core/UserSettingsController.cpp
+++ b/lldb/source/Core/UserSettingsController.cpp
@@ -53,10 +53,17 @@ Status Properties::SetPropertyValue(const ExecutionContext *exe_ctx,
 }
 
 void Properties::DumpAllPropertyValues(const ExecutionContext *exe_ctx,
-                                       Stream &strm, uint32_t dump_mask) {
+                                       Stream &strm, uint32_t dump_mask,
+                                       bool is_json) {
   OptionValuePropertiesSP properties_sp(GetValueProperties());
-  if (properties_sp)
-    return properties_sp->DumpValue(exe_ctx, strm, dump_mask);
+  if (!properties_sp)
+    return;
+
+  if (is_json) {
+    llvm::json::Value json = properties_sp->ToJSON(exe_ctx);
+    strm.Printf("%s", llvm::formatv("{0:2}", json).str().c_str());
+  } else
+    properties_sp->DumpValue(exe_ctx, strm, dump_mask);
 }
 
 void Properties::DumpAllDescriptions(CommandInterpreter &interpreter,
@@ -71,11 +78,11 @@ void Properties::DumpAllDescriptions(CommandInterpreter &interpreter,
 Status Properties::DumpPropertyValue(const ExecutionContext *exe_ctx,
                                      Stream &strm,
                                      llvm::StringRef property_path,
-                                     uint32_t dump_mask) {
+                                     uint32_t dump_mask, bool is_json) {
   OptionValuePropertiesSP properties_sp(GetValueProperties());
   if (properties_sp) {
     return properties_sp->DumpPropertyValue(exe_ctx, strm, property_path,
-                                            dump_mask);
+                                            dump_mask, is_json);
   }
   Status error;
   error.SetErrorString("empty property list");

diff  --git a/lldb/source/Interpreter/OptionValueArray.cpp b/lldb/source/Interpreter/OptionValueArray.cpp
index 07cb79e185063..40357d5f4b062 100644
--- a/lldb/source/Interpreter/OptionValueArray.cpp
+++ b/lldb/source/Interpreter/OptionValueArray.cpp
@@ -75,6 +75,14 @@ void OptionValueArray::DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
   }
 }
 
+llvm::json::Value OptionValueArray::ToJSON(const ExecutionContext *exe_ctx) {
+  llvm::json::Array json_array;
+  const uint32_t size = m_values.size();
+  for (uint32_t i = 0; i < size; ++i)
+    json_array.emplace_back(m_values[i]->ToJSON(exe_ctx));
+  return json_array;
+}
+
 Status OptionValueArray::SetValueFromString(llvm::StringRef value,
                                             VarSetOperationType op) {
   Args args(value.str());

diff  --git a/lldb/source/Interpreter/OptionValueDictionary.cpp b/lldb/source/Interpreter/OptionValueDictionary.cpp
index 6baafc9213e1a..d18510166eeb7 100644
--- a/lldb/source/Interpreter/OptionValueDictionary.cpp
+++ b/lldb/source/Interpreter/OptionValueDictionary.cpp
@@ -83,6 +83,15 @@ void OptionValueDictionary::DumpValue(const ExecutionContext *exe_ctx,
   }
 }
 
+llvm::json::Value
+OptionValueDictionary::ToJSON(const ExecutionContext *exe_ctx) {
+  llvm::json::Object dict;
+  for (const auto &value : m_values) {
+    dict.try_emplace(value.first.GetCString(), value.second->ToJSON(exe_ctx));
+  }
+  return dict;
+}
+
 size_t OptionValueDictionary::GetArgs(Args &args) const {
   args.Clear();
   collection::const_iterator pos, end = m_values.end();

diff  --git a/lldb/source/Interpreter/OptionValueFormat.cpp b/lldb/source/Interpreter/OptionValueFormat.cpp
index 76a446d1c3bc7..ab89f673e96fe 100644
--- a/lldb/source/Interpreter/OptionValueFormat.cpp
+++ b/lldb/source/Interpreter/OptionValueFormat.cpp
@@ -26,6 +26,10 @@ void OptionValueFormat::DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
   }
 }
 
+llvm::json::Value OptionValueFormat::ToJSON(const ExecutionContext *exe_ctx) {
+  return FormatManager::GetFormatAsCString(m_current_value);
+}
+
 Status OptionValueFormat::SetValueFromString(llvm::StringRef value,
                                              VarSetOperationType op) {
   Status error;

diff  --git a/lldb/source/Interpreter/OptionValueFormatEntity.cpp b/lldb/source/Interpreter/OptionValueFormatEntity.cpp
index 64fcaf2cbc850..98216e13ad83b 100644
--- a/lldb/source/Interpreter/OptionValueFormatEntity.cpp
+++ b/lldb/source/Interpreter/OptionValueFormatEntity.cpp
@@ -60,6 +60,13 @@ void OptionValueFormatEntity::DumpValue(const ExecutionContext *exe_ctx,
   }
 }
 
+llvm::json::Value
+OptionValueFormatEntity::ToJSON(const ExecutionContext *exe_ctx) {
+  std::string escaped;
+  EscapeBackticks(m_current_format, escaped);
+  return escaped;
+}
+
 Status OptionValueFormatEntity::SetValueFromString(llvm::StringRef value_str,
                                                    VarSetOperationType op) {
   Status error;

diff  --git a/lldb/source/Interpreter/OptionValueLanguage.cpp b/lldb/source/Interpreter/OptionValueLanguage.cpp
index d2fbe248300d8..1be8a5585bc4d 100644
--- a/lldb/source/Interpreter/OptionValueLanguage.cpp
+++ b/lldb/source/Interpreter/OptionValueLanguage.cpp
@@ -29,6 +29,10 @@ void OptionValueLanguage::DumpValue(const ExecutionContext *exe_ctx,
   }
 }
 
+llvm::json::Value OptionValueLanguage::ToJSON(const ExecutionContext *exe_ctx) {
+  return Language::GetNameForLanguageType(m_current_value);
+}
+
 Status OptionValueLanguage::SetValueFromString(llvm::StringRef value,
                                                VarSetOperationType op) {
   Status error;

diff  --git a/lldb/source/Interpreter/OptionValuePathMappings.cpp b/lldb/source/Interpreter/OptionValuePathMappings.cpp
index 438c9b7b96f0b..7cfc445f55809 100644
--- a/lldb/source/Interpreter/OptionValuePathMappings.cpp
+++ b/lldb/source/Interpreter/OptionValuePathMappings.cpp
@@ -34,6 +34,11 @@ void OptionValuePathMappings::DumpValue(const ExecutionContext *exe_ctx,
   }
 }
 
+llvm::json::Value
+OptionValuePathMappings::ToJSON(const ExecutionContext *exe_ctx) {
+  return m_path_mappings.ToJSON();
+}
+
 Status OptionValuePathMappings::SetValueFromString(llvm::StringRef value,
                                                    VarSetOperationType op) {
   Status error;

diff  --git a/lldb/source/Interpreter/OptionValueProperties.cpp b/lldb/source/Interpreter/OptionValueProperties.cpp
index b216557b808f8..c2c13ba97baa4 100644
--- a/lldb/source/Interpreter/OptionValueProperties.cpp
+++ b/lldb/source/Interpreter/OptionValueProperties.cpp
@@ -545,10 +545,26 @@ void OptionValueProperties::DumpValue(const ExecutionContext *exe_ctx,
   }
 }
 
+llvm::json::Value
+OptionValueProperties::ToJSON(const ExecutionContext *exe_ctx) {
+  llvm::json::Object json_properties;
+  const size_t num_properties = m_properties.size();
+  for (size_t i = 0; i < num_properties; ++i) {
+    const Property *property = GetPropertyAtIndex(exe_ctx, false, i);
+    if (property) {
+      OptionValue *option_value = property->GetValue().get();
+      assert(option_value);
+      json_properties.try_emplace(property->GetName(),
+                                  option_value->ToJSON(exe_ctx));
+    }
+  }
+  return json_properties;
+}
+
 Status OptionValueProperties::DumpPropertyValue(const ExecutionContext *exe_ctx,
                                                 Stream &strm,
                                                 llvm::StringRef property_path,
-                                                uint32_t dump_mask) {
+                                                uint32_t dump_mask, bool is_json) {
   Status error;
   const bool will_modify = false;
   lldb::OptionValueSP value_sp(
@@ -560,7 +576,10 @@ Status OptionValueProperties::DumpPropertyValue(const ExecutionContext *exe_ctx,
       if (dump_mask & ~eDumpOptionName)
         strm.PutChar(' ');
     }
-    value_sp->DumpValue(exe_ctx, strm, dump_mask);
+    if (is_json) {
+      strm.Printf("%s", llvm::formatv("{0:2}", value_sp->ToJSON(exe_ctx)).str().c_str());
+    } else
+      value_sp->DumpValue(exe_ctx, strm, dump_mask);
   }
   return error;
 }

diff  --git a/lldb/source/Target/PathMappingList.cpp b/lldb/source/Target/PathMappingList.cpp
index 4ebb175fcd85a..468048ccf2093 100644
--- a/lldb/source/Target/PathMappingList.cpp
+++ b/lldb/source/Target/PathMappingList.cpp
@@ -131,6 +131,16 @@ void PathMappingList::Dump(Stream *s, int pair_index) {
   }
 }
 
+llvm::json::Value PathMappingList::ToJSON() {
+  llvm::json::Array entries;
+  for (const auto &pair : m_pairs) {
+    llvm::json::Array entry{pair.first.GetStringRef().str(),
+                            pair.second.GetStringRef().str()};
+    entries.emplace_back(std::move(entry));
+  }
+  return entries;
+}
+
 void PathMappingList::Clear(bool notify) {
   if (!m_pairs.empty())
     ++m_mod_id;

diff  --git a/lldb/test/API/commands/settings/TestSettings.py b/lldb/test/API/commands/settings/TestSettings.py
index 0ea1e7b95e3d9..e50a4f385344d 100644
--- a/lldb/test/API/commands/settings/TestSettings.py
+++ b/lldb/test/API/commands/settings/TestSettings.py
@@ -3,7 +3,7 @@
 """
 
 
-
+import json
 import os
 import re
 import lldb
@@ -274,7 +274,7 @@ def do_test_run_args_and_env_vars(self, use_launchsimple):
         self.assertEqual(launch_info.GetArgumentAtIndex(0), "A")
         self.assertEqual(launch_info.GetArgumentAtIndex(1), "B")
         self.assertEqual(launch_info.GetArgumentAtIndex(2), "C")
-        
+
         self.expect(
             'target show-launch-environment',
             substrs=["MY_ENV_VAR=YES"])
@@ -787,3 +787,59 @@ def test_settings_set_exists(self):
 
         # A known option should fail if its argument is invalid.
         self.expect("settings set auto-confirm bogus", error=True)
+
+    def get_setting_json(self, setting_path = None):
+        settings_data = self.dbg.GetSetting(setting_path)
+        stream = lldb.SBStream()
+        settings_data.GetAsJSON(stream)
+        return json.loads(stream.GetData())
+
+    def verify_setting_value_json(self, setting_path, setting_value):
+        self.runCmd("settings set %s %s" % (setting_path, setting_value))
+        settings_json = self.get_setting_json(setting_path)
+        self.assertEqual(settings_json, setting_value)
+
+    def test_settings_api(self):
+        """
+            Test that ensures SBDebugger::GetSetting() APIs
+            can correctly fetch settings.
+        """
+
+        # Test basic values and embedding special JSON escaping characters.
+        self.runCmd("settings set auto-confirm true")
+        self.runCmd("settings set tab-size 2")
+        arg_value = "hello \"world\""
+        self.runCmd('settings set target.arg0 %s' % arg_value)
+
+        settings_json = self.get_setting_json()
+        self.assertEqual(settings_json["auto-confirm"], True)
+        self.assertEqual(settings_json["tab-size"], 2)
+        self.assertEqual(settings_json["target"]["arg0"], arg_value)
+
+        settings_data = self.get_setting_json("target.arg0")
+        self.assertEqual(settings_data, arg_value)
+
+        # Test OptionValueFileSpec
+        self.verify_setting_value_json("platform.module-cache-directory", self.get_process_working_directory())
+
+        # Test OptionValueArray
+        setting_path = "target.run-args"
+        setting_value = ["value1", "value2", "value3"]
+        self.runCmd("settings set %s %s" % (setting_path, " ".join(setting_value)))
+        settings_json = self.get_setting_json(setting_path)
+        self.assertEqual(settings_json, setting_value)
+
+        # Test OptionValueFormatEntity
+        setting_value = """thread #${thread.index}{, name = \\'${thread.name}\\
+        '}{, queue = ${ansi.fg.green}\\'${thread.queue}\\'${ansi.normal}}{,
+        activity = ${ansi.fg.green}\\'${thread.info.activity.name}\\'${ansi.normal}}
+        {, ${thread.info.trace_messages} messages}{, stop reason = ${ansi.fg.red}$
+        {thread.stop-reason}${ansi.normal}}{\\\\nReturn value: ${thread.return-value}}
+        {\\\\nCompleted expression: ${thread.completed-expression}}\\\\n"""
+        self.verify_setting_value_json("thread-stop-format", setting_value)
+
+        # Test OptionValueRegex
+        self.verify_setting_value_json("target.process.thread.step-avoid-regexp", "^std::")
+
+        # Test OptionValueLanguage
+        self.verify_setting_value_json("repl-lang", "c++")

diff  --git a/lldb/test/API/functionalities/source-map/TestTargetSourceMap.py b/lldb/test/API/functionalities/source-map/TestTargetSourceMap.py
index 129365abbf215..c1b45653341dd 100644
--- a/lldb/test/API/functionalities/source-map/TestTargetSourceMap.py
+++ b/lldb/test/API/functionalities/source-map/TestTargetSourceMap.py
@@ -1,11 +1,45 @@
 import lldb
 from lldbsuite.test.lldbtest import *
 from lldbsuite.test.decorators import *
+import json
 import os
 
 
 class TestTargetSourceMap(TestBase):
 
+    @no_debug_info_test
+    def test_source_map_via_setting_api(self):
+        """
+            Test that ensures SBDebugger::GetSetting("target.source-map") API
+            can correctly fetch source mapping entries.
+        """
+        # Set the target soure map to map "./" to the current test directory
+        src_dir = self.getSourceDir()
+
+        source_map_setting_path = "target.source-map"
+        initial_source_map = self.dbg.GetSetting(source_map_setting_path)
+        self.assertEquals(initial_source_map.GetSize(), 0,
+            "Initial source map should be empty")
+
+        src_dir = self.getSourceDir()
+        self.runCmd('settings set %s . "%s"' % (source_map_setting_path, src_dir))
+
+        source_map = self.dbg.GetSetting(source_map_setting_path)
+        self.assertEquals(source_map.GetSize(), 1,
+            "source map should be have one appended entry")
+
+        stream = lldb.SBStream()
+        source_map.GetAsJSON(stream)
+        serialized_source_map = json.loads(stream.GetData())
+
+        self.assertEquals(len(serialized_source_map[0]), 2,
+            "source map entry should have two parts")
+        self.assertEquals(serialized_source_map[0][0], ".",
+            "source map entry's first part does not match")
+        self.assertEquals(serialized_source_map[0][1], src_dir,
+            "source map entry's second part does not match")
+
+
     @no_debug_info_test
     def test_source_map(self):
         """Test target.source-map' functionality."""


        


More information about the lldb-commits mailing list