[Lldb-commits] [lldb] [lldb][ClangExpressionParser] Don't by default enable Objecitve-C support when evaluating C++ expressions (PR #87767)
Michael Buch via lldb-commits
lldb-commits at lists.llvm.org
Thu Apr 11 11:29:46 PDT 2024
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/87767
>From f27a547ab85463f182ab63949bb6f11140a2f33f Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 5 Apr 2024 11:51:47 +0100
Subject: [PATCH 1/2] [lldb][ClangExpressionParser] Don't by default enable
Objecitve-C support when evaluating C++ expressions
This patch attempts to decouple C++ expression evaluation from
Objective-C support. We've previously enabled it by default
(if a runtime existed), but that meant we're opting into extra
work we only need to do for Objective-C, which complicates/slows down
C++ expression evaluation. Of course there's a valid use-case for this,
which is calling Objective-C APIs when stopped in C++ frames (which
Objective-C++ developers might want to do). In those case we should
really prompt the user to add the `expr --language objc++` flag.
To accomodate a likely frequent use-case where a user breaks in a system
C++ library (without debug-symbols) but their application is actually
an Objective-C app, we allow Objective-C support in C++ expressions
if the current frame doesn't have debug-info.
This fixes https://github.com/llvm/llvm-project/issues/75443 and
allows us to add more `LangOpts.ObjC` guards around the expression
evaluator in the future (e.g., we could avoid looking into the
Objective-C runtime during C++ expression evaluation, which we
currently do unconditionally).
Depends on https://github.com/llvm/llvm-project/pull/87657
---
.../Clang/ClangExpressionParser.cpp | 5 ++++-
.../diagnostics/TestExprDiagnostics.py | 2 +-
.../expression/options/TestExprOptions.py | 1 -
.../objc-builtin-types/TestObjCBuiltinTypes.py | 2 +-
.../Makefile | 4 ++++
.../TestObjCFromCppFramesWithoutDebugInfo.py | 17 +++++++++++++++++
.../main.cpp | 1 +
7 files changed, 28 insertions(+), 4 deletions(-)
create mode 100644 lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/Makefile
create mode 100644 lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/TestObjCFromCppFramesWithoutDebugInfo.py
create mode 100644 lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/main.cpp
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 822d286cd6c3c4..f48bdc730d9160 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -526,7 +526,10 @@ ClangExpressionParser::ClangExpressionParser(
[[fallthrough]];
case lldb::eLanguageTypeC_plus_plus_03:
lang_opts.CPlusPlus = true;
- if (process_sp)
+ if (process_sp
+ // We're stopped in a frame without debug-info. The user probably
+ // intends to make global queries (which should include Objective-C).
+ && !(frame_sp && frame_sp->HasDebugInformation()))
lang_opts.ObjC =
process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC) != nullptr;
break;
diff --git a/lldb/test/API/commands/expression/diagnostics/TestExprDiagnostics.py b/lldb/test/API/commands/expression/diagnostics/TestExprDiagnostics.py
index d64e9897a844f1..ddc1c3598480cf 100644
--- a/lldb/test/API/commands/expression/diagnostics/TestExprDiagnostics.py
+++ b/lldb/test/API/commands/expression/diagnostics/TestExprDiagnostics.py
@@ -172,7 +172,7 @@ def test_source_locations_from_objc_modules(self):
# Import foundation so that the Obj-C module is loaded (which contains source locations
# that can be used by LLDB).
- self.runCmd("expr @import Foundation")
+ self.runCmd("expr --language objective-c++ -- @import Foundation")
value = frame.EvaluateExpression("NSLog(1);")
self.assertFalse(value.GetError().Success())
# LLDB should print the source line that defines NSLog. To not rely on any
diff --git a/lldb/test/API/commands/expression/options/TestExprOptions.py b/lldb/test/API/commands/expression/options/TestExprOptions.py
index 6652c71083a958..01899f3b97cf44 100644
--- a/lldb/test/API/commands/expression/options/TestExprOptions.py
+++ b/lldb/test/API/commands/expression/options/TestExprOptions.py
@@ -59,7 +59,6 @@ def test_expr_options(self):
self.assertTrue(val.IsValid())
self.assertFalse(val.GetError().Success())
- @skipIfDarwin
def test_expr_options_lang(self):
"""These expression language options should work as expected."""
self.build()
diff --git a/lldb/test/API/lang/objcxx/objc-builtin-types/TestObjCBuiltinTypes.py b/lldb/test/API/lang/objcxx/objc-builtin-types/TestObjCBuiltinTypes.py
index 1eb7205f1bb465..280994fbde71ab 100644
--- a/lldb/test/API/lang/objcxx/objc-builtin-types/TestObjCBuiltinTypes.py
+++ b/lldb/test/API/lang/objcxx/objc-builtin-types/TestObjCBuiltinTypes.py
@@ -53,5 +53,5 @@ def test_with_python_api(self):
)
self.expect(
"expr --language C++ -- id my_id = 0; my_id",
- patterns=["\(id\) \$.* = nullptr"],
+ error=True
)
diff --git a/lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/Makefile b/lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/Makefile
new file mode 100644
index 00000000000000..7c3c32d6f82df4
--- /dev/null
+++ b/lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/Makefile
@@ -0,0 +1,4 @@
+CXX_SOURCES := main.cpp
+CXXFLAGS_EXTRAS := -g0
+
+include Makefile.rules
diff --git a/lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/TestObjCFromCppFramesWithoutDebugInfo.py b/lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/TestObjCFromCppFramesWithoutDebugInfo.py
new file mode 100644
index 00000000000000..ba33d44732c924
--- /dev/null
+++ b/lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/TestObjCFromCppFramesWithoutDebugInfo.py
@@ -0,0 +1,17 @@
+"""
+Test that the the expression parser enables ObjC support
+when stopped in a C++ frame without debug-info.
+"""
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestObjCFromCppFramesWithoutDebugInfo(TestBase):
+ def test(self):
+ self.build()
+ (_, process, _, _) = lldbutil.run_to_name_breakpoint(self, "main")
+
+ self.assertState(process.GetState(), lldb.eStateStopped)
+ self.expect("expr id", error=False)
diff --git a/lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/main.cpp b/lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/main.cpp
new file mode 100644
index 00000000000000..76e8197013aabc
--- /dev/null
+++ b/lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/main.cpp
@@ -0,0 +1 @@
+int main() { return 0; }
>From 3919045a75cc36dc4e14c7f087792436d2c52df4 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 5 Apr 2024 12:05:21 +0100
Subject: [PATCH 2/2] fixup! python format
---
.../lang/objcxx/objc-builtin-types/TestObjCBuiltinTypes.py | 5 +----
.../TestObjCFromCppFramesWithoutDebugInfo.py | 1 +
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/lldb/test/API/lang/objcxx/objc-builtin-types/TestObjCBuiltinTypes.py b/lldb/test/API/lang/objcxx/objc-builtin-types/TestObjCBuiltinTypes.py
index 280994fbde71ab..611c7388999058 100644
--- a/lldb/test/API/lang/objcxx/objc-builtin-types/TestObjCBuiltinTypes.py
+++ b/lldb/test/API/lang/objcxx/objc-builtin-types/TestObjCBuiltinTypes.py
@@ -51,7 +51,4 @@ def test_with_python_api(self):
"expr --language Objective-C++ -- id my_id = 0; my_id",
patterns=["\(id\) \$.* = nil"],
)
- self.expect(
- "expr --language C++ -- id my_id = 0; my_id",
- error=True
- )
+ self.expect("expr --language C++ -- id my_id = 0; my_id", error=True)
diff --git a/lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/TestObjCFromCppFramesWithoutDebugInfo.py b/lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/TestObjCFromCppFramesWithoutDebugInfo.py
index ba33d44732c924..ef8d5540fa4ef9 100644
--- a/lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/TestObjCFromCppFramesWithoutDebugInfo.py
+++ b/lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/TestObjCFromCppFramesWithoutDebugInfo.py
@@ -8,6 +8,7 @@
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
+
class TestObjCFromCppFramesWithoutDebugInfo(TestBase):
def test(self):
self.build()
More information about the lldb-commits
mailing list