Skip to content

Commit 38f8fce

Browse files
authored
[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 #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 #87657
1 parent fc52ee3 commit 38f8fce

File tree

7 files changed

+29
-7
lines changed

7 files changed

+29
-7
lines changed

lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,10 @@ ClangExpressionParser::ClangExpressionParser(
526526
[[fallthrough]];
527527
case lldb::eLanguageTypeC_plus_plus_03:
528528
lang_opts.CPlusPlus = true;
529-
if (process_sp)
529+
if (process_sp
530+
// We're stopped in a frame without debug-info. The user probably
531+
// intends to make global queries (which should include Objective-C).
532+
&& !(frame_sp && frame_sp->HasDebugInformation()))
530533
lang_opts.ObjC =
531534
process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC) != nullptr;
532535
break;

lldb/test/API/commands/expression/diagnostics/TestExprDiagnostics.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ def test_source_locations_from_objc_modules(self):
172172

173173
# Import foundation so that the Obj-C module is loaded (which contains source locations
174174
# that can be used by LLDB).
175-
self.runCmd("expr @import Foundation")
175+
self.runCmd("expr --language objective-c++ -- @import Foundation")
176176
value = frame.EvaluateExpression("NSLog(1);")
177177
self.assertFalse(value.GetError().Success())
178178
# LLDB should print the source line that defines NSLog. To not rely on any

lldb/test/API/commands/expression/options/TestExprOptions.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ def test_expr_options(self):
5959
self.assertTrue(val.IsValid())
6060
self.assertFalse(val.GetError().Success())
6161

62-
@skipIfDarwin
6362
def test_expr_options_lang(self):
6463
"""These expression language options should work as expected."""
6564
self.build()

lldb/test/API/lang/objcxx/objc-builtin-types/TestObjCBuiltinTypes.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,4 @@ def test_with_python_api(self):
5151
"expr --language Objective-C++ -- id my_id = 0; my_id",
5252
patterns=["\(id\) \$.* = nil"],
5353
)
54-
self.expect(
55-
"expr --language C++ -- id my_id = 0; my_id",
56-
patterns=["\(id\) \$.* = nullptr"],
57-
)
54+
self.expect("expr --language C++ -- id my_id = 0; my_id", error=True)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
CXX_SOURCES := main.cpp
2+
CXXFLAGS_EXTRAS := -g0
3+
4+
include Makefile.rules
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"""
2+
Test that the the expression parser enables ObjC support
3+
when stopped in a C++ frame without debug-info.
4+
"""
5+
6+
import lldb
7+
from lldbsuite.test.decorators import *
8+
from lldbsuite.test.lldbtest import *
9+
from lldbsuite.test import lldbutil
10+
11+
12+
class TestObjCFromCppFramesWithoutDebugInfo(TestBase):
13+
def test(self):
14+
self.build()
15+
(_, process, _, _) = lldbutil.run_to_name_breakpoint(self, "main")
16+
17+
self.assertState(process.GetState(), lldb.eStateStopped)
18+
self.expect("expr id", error=False)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
int main() { return 0; }

0 commit comments

Comments
 (0)