[Lldb-commits] [lldb] 38f8fce - [lldb][ClangExpressionParser] Don't by default enable Objecitve-C support when evaluating C++ expressions (#87767)

via lldb-commits lldb-commits at lists.llvm.org
Thu Apr 11 11:30:52 PDT 2024


Author: Michael Buch
Date: 2024-04-11T20:30:48+02:00
New Revision: 38f8fcea3455ef1d77faf9746579f52b4e18dacc

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

LOG: [lldb][ClangExpressionParser] Don't by default enable Objecitve-C support when evaluating C++ expressions (#87767)

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 cases 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

Added: 
    lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/Makefile
    lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/TestObjCFromCppFramesWithoutDebugInfo.py
    lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/main.cpp

Modified: 
    lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
    lldb/test/API/commands/expression/diagnostics/TestExprDiagnostics.py
    lldb/test/API/commands/expression/options/TestExprOptions.py
    lldb/test/API/lang/objcxx/objc-builtin-types/TestObjCBuiltinTypes.py

Removed: 
    


################################################################################
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..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",
-            patterns=["\(id\) \$.* = nullptr"],
-        )
+        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/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..ef8d5540fa4ef9
--- /dev/null
+++ b/lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/TestObjCFromCppFramesWithoutDebugInfo.py
@@ -0,0 +1,18 @@
+"""
+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; }


        


More information about the lldb-commits mailing list