[Lldb-commits] [lldb] [lldb] Limit DIL globals to only current file (PR #192592)
Dave Lee via lldb-commits
lldb-commits at lists.llvm.org
Thu Apr 16 21:48:34 PDT 2026
https://github.com/kastiglione created https://github.com/llvm/llvm-project/pull/192592
DIL has supported unlimited global lookup, which is in contrast with legacy
`frame variable` behavior, which supports only globals in the current file.
This is semantically incorrect for `frame variable`, and has shown to produce
bugs in `dwim-print`. For these reasons, this change proposes limiting DIL
globals to only globals from the current compilation unit.
For `dwim-print`, the bug manifests as when a global shadows a computed
property of the instance variable (`self`). As an example, if a global named
`text` exists, and a property named `text` exists (ie `self.text`), then
running `dwim-print text` will unexpectedly print the global, not `self.text`.
Assisted-by: claude
>From 3c5f71d6c496dfb48b15067a314f6ba2f0817c9f Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Thu, 16 Apr 2026 21:39:51 -0700
Subject: [PATCH] [lldb] Limit DIL globals to only current file
DIL has supported unlimited global lookup, which is in contrast with legacy
`frame variable` behavior, which supports only globals in the current file.
This is semantically incorrect for `frame variable`, and has shown to produce
bugs in `dwim-print`. For these reasons, this change proposes limiting DIL
globals to only globals from the current compilation unit.
For `dwim-print`, the bug manifests as when a global shadows a computed
property of the instance variable (`self`). As an example, if a global named
`text` exists, and a property named `text` exists (ie `self.text`), then
running `dwim-print text` will unexpectedly print the global, not `self.text`.
Assisted-by: claude
---
lldb/include/lldb/ValueObject/DILEval.h | 7 +++---
lldb/source/ValueObject/DILEval.cpp | 25 +++----------------
lldb/source/ValueObject/DILParser.cpp | 3 +--
.../TestFrameVarDILGlobalVariableLookup.py | 23 ++++++++++++-----
4 files changed, 24 insertions(+), 34 deletions(-)
diff --git a/lldb/include/lldb/ValueObject/DILEval.h b/lldb/include/lldb/ValueObject/DILEval.h
index c5f41b5a0bc76..ec495b4ea9061 100644
--- a/lldb/include/lldb/ValueObject/DILEval.h
+++ b/lldb/include/lldb/ValueObject/DILEval.h
@@ -28,12 +28,11 @@ lldb::ValueObjectSP LookupIdentifier(llvm::StringRef name_ref,
lldb::DynamicValueType use_dynamic);
/// Given the name of an identifier, check to see if it matches the name of a
-/// global variable. If so, find the ValueObject for that global variable, and
-/// create and return an IdentifierInfo object containing all the relevant
-/// informatin about it.
+/// global variable in the current compile unit. If so, find the ValueObject for
+/// that global variable, and create and return an IdentifierInfo object
+/// containing all the relevant information about it.
lldb::ValueObjectSP LookupGlobalIdentifier(llvm::StringRef name_ref,
std::shared_ptr<StackFrame> frame_sp,
- lldb::TargetSP target_sp,
lldb::DynamicValueType use_dynamic);
class Interpreter : Visitor {
diff --git a/lldb/source/ValueObject/DILEval.cpp b/lldb/source/ValueObject/DILEval.cpp
index 7801b9225f19e..228524b00256d 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -16,7 +16,6 @@
#include "lldb/ValueObject/DILParser.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/ValueObject/ValueObjectRegister.h"
-#include "lldb/ValueObject/ValueObjectVariable.h"
#include "llvm/Support/FormatAdapters.h"
#include <memory>
@@ -293,7 +292,7 @@ static lldb::VariableSP DILFindVariable(ConstString name,
lldb::ValueObjectSP LookupGlobalIdentifier(
llvm::StringRef name_ref, std::shared_ptr<StackFrame> stack_frame,
- lldb::TargetSP target_sp, lldb::DynamicValueType use_dynamic) {
+ lldb::DynamicValueType use_dynamic) {
// Get a global variables list without the locals from the current frame
SymbolContext symbol_context =
stack_frame->GetSymbolContext(lldb::eSymbolContextCompUnit);
@@ -311,25 +310,7 @@ lldb::ValueObjectSP LookupGlobalIdentifier(
stack_frame->GetValueObjectForFrameVariable(var_sp, use_dynamic);
}
- if (value_sp)
- return value_sp;
-
- // Check for match in modules global variables.
- VariableList modules_var_list;
- target_sp->GetImages().FindGlobalVariables(
- ConstString(name_ref), std::numeric_limits<uint32_t>::max(),
- modules_var_list);
-
- if (!modules_var_list.Empty()) {
- lldb::VariableSP var_sp =
- DILFindVariable(ConstString(name_ref), modules_var_list);
- if (var_sp)
- value_sp = ValueObjectVariable::Create(stack_frame.get(), var_sp);
-
- if (value_sp)
- return value_sp;
- }
- return nullptr;
+ return value_sp;
}
lldb::ValueObjectSP LookupIdentifier(llvm::StringRef name_ref,
@@ -438,7 +419,7 @@ Interpreter::Visit(const IdentifierNode &node) {
if (!identifier)
identifier = LookupGlobalIdentifier(node.GetName(), m_exe_ctx_scope,
- m_target, use_dynamic);
+ use_dynamic);
if (!identifier) {
std::string errMsg =
llvm::formatv("use of undeclared identifier '{0}'", node.GetName());
diff --git a/lldb/source/ValueObject/DILParser.cpp b/lldb/source/ValueObject/DILParser.cpp
index 51bdffd5087ca..9fb7206429555 100644
--- a/lldb/source/ValueObject/DILParser.cpp
+++ b/lldb/source/ValueObject/DILParser.cpp
@@ -479,8 +479,7 @@ std::optional<CompilerType> DILParser::ParseTypeId() {
return {};
// Same-name identifiers should be preferred over typenames.
- if (LookupGlobalIdentifier(type_name, m_ctx_scope,
- m_ctx_scope->CalculateTarget(), m_use_dynamic))
+ if (LookupGlobalIdentifier(type_name, m_ctx_scope, m_use_dynamic))
// TODO: Make type accessible with 'class', 'struct' and 'union' keywords
return {};
}
diff --git a/lldb/test/API/commands/frame/var-dil/basics/GlobalVariableLookup/TestFrameVarDILGlobalVariableLookup.py b/lldb/test/API/commands/frame/var-dil/basics/GlobalVariableLookup/TestFrameVarDILGlobalVariableLookup.py
index 5c91755ed0db6..0a59e565d976f 100644
--- a/lldb/test/API/commands/frame/var-dil/basics/GlobalVariableLookup/TestFrameVarDILGlobalVariableLookup.py
+++ b/lldb/test/API/commands/frame/var-dil/basics/GlobalVariableLookup/TestFrameVarDILGlobalVariableLookup.py
@@ -49,12 +49,23 @@ def test_frame_var(self):
self.expect_var_path("::ns::globalPtr", type="int *")
self.expect_var_path("::ns::globalRef", type="int &")
- self.expect_var_path("externGlobalVar", value="2")
- self.expect_var_path("::externGlobalVar", value="2")
- self.expect_var_path("ext::externGlobalVar", value="4")
- self.expect_var_path("::ext::externGlobalVar", value="4")
-
- self.expect_var_path("ExtStruct::static_inline", value="16")
+ # Globals from other compile units are not accessible (matching legacy
+ # frame var behavior).
+ self.expect(
+ "frame var externGlobalVar",
+ error=True,
+ substrs=["use of undeclared identifier"],
+ )
+ self.expect(
+ "frame var ext::externGlobalVar",
+ error=True,
+ substrs=["use of undeclared identifier"],
+ )
+ self.expect(
+ "frame var ExtStruct::static_inline",
+ error=True,
+ substrs=["use of undeclared identifier"],
+ )
# Test local variable priority over global
self.expect_var_path("foo", value="1")
More information about the lldb-commits
mailing list