[Lldb-commits] [lldb] 72b1c13 - [lldb] Add enum lookup to DIL (#192065)
via lldb-commits
lldb-commits at lists.llvm.org
Mon May 25 07:11:32 PDT 2026
Author: Ilia Kuklin
Date: 2026-05-25T19:11:27+05:00
New Revision: 72b1c13378f6236956df37f9f8f621c7e60d32a6
URL: https://github.com/llvm/llvm-project/commit/72b1c13378f6236956df37f9f8f621c7e60d32a6
DIFF: https://github.com/llvm/llvm-project/commit/72b1c13378f6236956df37f9f8f621c7e60d32a6.diff
LOG: [lldb] Add enum lookup to DIL (#192065)
Added:
lldb/test/API/commands/frame/var-dil/expr/EnumValueLookup/Makefile
lldb/test/API/commands/frame/var-dil/expr/EnumValueLookup/TestEnumValueLookup.py
lldb/test/API/commands/frame/var-dil/expr/EnumValueLookup/main.cpp
Modified:
lldb/include/lldb/ValueObject/DILEval.h
lldb/include/lldb/ValueObject/DILParser.h
lldb/source/ValueObject/DILEval.cpp
lldb/source/ValueObject/DILParser.cpp
Removed:
################################################################################
diff --git a/lldb/include/lldb/ValueObject/DILEval.h b/lldb/include/lldb/ValueObject/DILEval.h
index 5965004cd5883..a67c9e81e2898 100644
--- a/lldb/include/lldb/ValueObject/DILEval.h
+++ b/lldb/include/lldb/ValueObject/DILEval.h
@@ -36,6 +36,11 @@ lldb::ValueObjectSP LookupGlobalIdentifier(llvm::StringRef name_ref,
lldb::TargetSP target_sp,
lldb::DynamicValueType use_dynamic);
+/// Given the name of an identifier, attempt to find an enumeration value.
+/// If found, return a ValueObject with a const scalar value of the enum.
+lldb::ValueObjectSP LookupEnumValue(llvm::StringRef name_ref,
+ ExecutionContextScope &ctx_scope);
+
class Interpreter : Visitor {
public:
Interpreter(lldb::TargetSP target, llvm::StringRef expr,
diff --git a/lldb/include/lldb/ValueObject/DILParser.h b/lldb/include/lldb/ValueObject/DILParser.h
index 53e56c9e6837c..4d1ede2e62900 100644
--- a/lldb/include/lldb/ValueObject/DILParser.h
+++ b/lldb/include/lldb/ValueObject/DILParser.h
@@ -35,6 +35,9 @@ enum class ErrorCode : unsigned char {
kUnknown,
};
+CompilerType ResolveTypeByName(const std::string &name,
+ ExecutionContextScope &ctx_scope);
+
// The following is modeled on class OptionParseError.
class DILDiagnosticError
: public llvm::ErrorInfo<DILDiagnosticError, DiagnosticError> {
diff --git a/lldb/source/ValueObject/DILEval.cpp b/lldb/source/ValueObject/DILEval.cpp
index 82af0bf4ee7e7..b224e12730723 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -372,6 +372,31 @@ lldb::ValueObjectSP LookupIdentifier(llvm::StringRef name_ref,
return nullptr;
}
+lldb::ValueObjectSP LookupEnumValue(llvm::StringRef name_ref,
+ ExecutionContextScope &ctx_scope) {
+ if (name_ref.contains("::")) {
+ llvm::StringRef enum_typename, enumerator_name;
+ // FIXME: Change this to a structured binding for lambda capturing
+ // once we have C++20.
+ std::tie(enum_typename, enumerator_name) = name_ref.rsplit("::");
+ CompilerType enum_type = ResolveTypeByName(enum_typename.str(), ctx_scope);
+ lldb::ValueObjectSP result;
+ enum_type.ForEachEnumerator([&](const CompilerType &integer_type,
+ ConstString name,
+ const llvm::APSInt &value) -> bool {
+ if (name == enumerator_name) {
+ Scalar scalar(value);
+ result = ValueObject::CreateValueObjectFromScalar(ctx_scope, scalar,
+ enum_type, "result");
+ return false; // Stop iterating
+ }
+ return true;
+ });
+ return result;
+ }
+ return nullptr;
+}
+
Interpreter::Interpreter(lldb::TargetSP target, llvm::StringRef expr,
std::shared_ptr<StackFrame> frame_sp,
lldb::DynamicValueType use_dynamic, uint32_t options)
@@ -431,6 +456,10 @@ Interpreter::Visit(const IdentifierNode &node) {
if (!identifier && m_allow_globals)
identifier = LookupGlobalIdentifier(node.GetName(), m_exe_ctx_scope,
m_target, use_dynamic);
+
+ if (!identifier)
+ identifier = LookupEnumValue(node.GetName(), *m_exe_ctx_scope);
+
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 7e0f8896f6fcb..2393892e97d49 100644
--- a/lldb/source/ValueObject/DILParser.cpp
+++ b/lldb/source/ValueObject/DILParser.cpp
@@ -59,8 +59,8 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_str);
}
-static CompilerType ResolveTypeByName(const std::string &name,
- ExecutionContextScope &ctx_scope) {
+CompilerType ResolveTypeByName(const std::string &name,
+ ExecutionContextScope &ctx_scope) {
// Internally types don't have global scope qualifier in their names and
// LLDB doesn't support queries with it too.
llvm::StringRef name_ref(name);
diff --git a/lldb/test/API/commands/frame/var-dil/expr/EnumValueLookup/Makefile b/lldb/test/API/commands/frame/var-dil/expr/EnumValueLookup/Makefile
new file mode 100644
index 0000000000000..99998b20bcb05
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/expr/EnumValueLookup/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/commands/frame/var-dil/expr/EnumValueLookup/TestEnumValueLookup.py b/lldb/test/API/commands/frame/var-dil/expr/EnumValueLookup/TestEnumValueLookup.py
new file mode 100644
index 0000000000000..e0a0ffd6be048
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/expr/EnumValueLookup/TestEnumValueLookup.py
@@ -0,0 +1,36 @@
+"""
+Test DIL enum value lookups.
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from lldbsuite.test import lldbutil
+
+
+class TestEnumValueLookup(TestBase):
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def test_literals(self):
+ self.build()
+ (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
+ self, "Set a breakpoint here", lldb.SBFileSpec("main.cpp")
+ )
+
+ self.runCmd("settings set target.experimental.use-DIL true")
+
+ self.expect_var_path("enum_one", value="kOne", type="UnscopedEnum")
+ self.expect_var_path("UnscopedEnum::kOne", value="kOne", type="UnscopedEnum")
+ self.expect_var_path(
+ "UnscopedEnumInt8::kOne8", value="kOne8", type="UnscopedEnumInt8"
+ )
+ self.expect_var_path("ScopedEnum::kOneS", value="kOneS", type="ScopedEnum")
+ self.expect_var_path(
+ "ns::NSUnscopedEnum::kOneNS", value="kOneNS", type="ns::NSUnscopedEnum"
+ )
+
+ # Check the underlying type
+ frame = thread.GetFrameAtIndex(0)
+ kOne8 = frame.GetValueForVariablePath("UnscopedEnumInt8::kOne8")
+ underlying_type = kOne8.GetType().GetEnumerationIntegerType().GetName()
+ self.assertEqual(underlying_type, "int8_t")
diff --git a/lldb/test/API/commands/frame/var-dil/expr/EnumValueLookup/main.cpp b/lldb/test/API/commands/frame/var-dil/expr/EnumValueLookup/main.cpp
new file mode 100644
index 0000000000000..6e801da2120bc
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/expr/EnumValueLookup/main.cpp
@@ -0,0 +1,19 @@
+#include <cstdint>
+
+enum UnscopedEnum { kZero, kOne };
+enum UnscopedEnumInt8 : int8_t { kZero8, kOne8 };
+enum class ScopedEnum { kZeroS, kOneS };
+namespace ns {
+enum NSUnscopedEnum { kZeroNS, kOneNS };
+}
+
+void stop() {}
+int main(int argc, char **argv) {
+ auto enum_one = UnscopedEnum::kOne;
+ auto enum_one_8 = UnscopedEnumInt8::kOne8;
+ auto sc_enum_one = ScopedEnum::kOneS;
+ auto ns_enum_one = ns::NSUnscopedEnum::kOneNS;
+
+ stop(); // Set a breakpoint here
+ return 0;
+}
More information about the lldb-commits
mailing list