================
@@ -27,285 +26,394 @@
 using namespace lldb_dap;
 using namespace lldb_dap::protocol;
 
-namespace lldb_dap {
-
-protocol::Scope CreateScope(ScopeKind kind, var_ref_t variablesReference,
-                            bool expensive) {
-  protocol::Scope scope;
-  scope.variablesReference = variablesReference;
-  scope.expensive = expensive;
+namespace {
+
+/// A Variable store for fetching variables within a specific scope (locals,
+/// globals, or registers) for a given stack frame.
+class ScopeStore final : public VariableStore {
+public:
+  explicit ScopeStore(ScopeKind kind, const lldb::SBFrame &frame)
+      : m_frame(frame), m_kind(kind) {}
+
+  std::vector<protocol::Variable>
+  GetVariables(VariableReferenceStorage &storage,
+               const protocol::Configuration &config,
+               const protocol::VariablesArguments &args) override {
+    LoadVariables();
+    if (m_kind == lldb_dap::eScopeKindRegisters)
+      SetRegistersFormat();
+
+    const bool format_hex = args.format ? args.format->hex : false;
+    std::vector<Variable> variables;
+    if (m_kind == eScopeKindLocals)
+      AddReturnValue(storage, config, variables, format_hex);
+
+    const uint64_t count = args.count;
+    const uint32_t start_idx = 0;
+    const uint32_t num_children = m_children.GetSize();
+    const uint32_t end_idx = start_idx + ((count == 0) ? num_children : count);
+
+    // We first find out which variable names are duplicated.
+    std::map<llvm::StringRef, uint32_t> variable_name_counts;
+    for (auto i = start_idx; i < end_idx; ++i) {
+      lldb::SBValue variable = m_children.GetValueAtIndex(i);
+      if (!variable.IsValid())
+        break;
+      variable_name_counts[GetNonNullVariableName(variable)]++;
+    }
 
-  // TODO: Support "arguments" and "return value" scope.
-  // At the moment lldb-dap includes the arguments and return_value  into the
-  // "locals" scope.
-  // VS Code only expands the first non-expensive scope. This causes friction
-  // if we add the arguments above the local scope, as the locals scope will 
not
-  // be expanded if we enter a function with arguments. It becomes more
-  // annoying when the scope has arguments, return_value and locals.
-  switch (kind) {
-  case eScopeKindLocals:
-    scope.presentationHint = protocol::Scope::eScopePresentationHintLocals;
-    scope.name = "Locals";
-    break;
-  case eScopeKindGlobals:
-    scope.name = "Globals";
-    break;
-  case eScopeKindRegisters:
-    scope.presentationHint = protocol::Scope::eScopePresentationHintRegisters;
-    scope.name = "Registers";
-    break;
+    // Now we construct the result with unique display variable names.
+    for (auto i = start_idx; i < end_idx; ++i) {
+      lldb::SBValue variable = m_children.GetValueAtIndex(i);
+
+      if (!variable.IsValid())
+        break;
+
+      const var_ref_t frame_var_ref =
+          storage.Insert(variable, /*is_permanent=*/false);
+      if (LLVM_UNLIKELY(frame_var_ref.AsUInt32() >=
+                        var_ref_t::k_variables_reference_threshold)) {
+        DAP_LOG(storage.log,
+                "warning: scopes variablesReference threshold reached. "
+                "current: {} threshold: {}, maximum {}.",
+                frame_var_ref.AsUInt32(),
+                var_ref_t::k_variables_reference_threshold,
+                var_ref_t::k_max_variables_references);
+      }
+
+      if (LLVM_UNLIKELY(frame_var_ref.Kind() == eReferenceKindInvalid))
+        break;
----------------
DrSergei wrote:

Maybe better to add logs here like in `ExpandableValueStore`

https://github.com/llvm/llvm-project/pull/183176
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to