Skip to content

Commit

Permalink
Reland "[lldb][ObjC] Don't query objective-c runtime for decls in C++…
Browse files Browse the repository at this point in the history
… contexts"

This relands llvm#95963. It had to
be reverted because the `TestEarlyProcessLaunch.py` test was failing
on the incremental macOS bots. The test failed because it was relying on
expression log output from the ObjC introspection routines (but was
the expression was called from a C++ context). The relanded patch
simply ensures that the test runs the expressions as `ObjC` expressions.

When LLDB isn't able to find a `clang::Decl` in response
to a `FindExternalVisibleDeclsByName`, it will fall-back
to looking into the Objective-C runtime for that decl. This
ends up doing a lot of work which isn't necessary when we're
debugging a C++ program. This patch makes the ObjC lookup
conditional on the language that the ExpressionParser deduced
(which can be explicitly set using the `expr --language` option
or is set implicitly if we're stopped in an ObjC frame or a
C++ frame without debug-info).

rdar://96236519
  • Loading branch information
Michael137 committed Jun 21, 2024
1 parent ad39315 commit 9e6ea38
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@ void ClangASTSource::FindExternalVisibleDecls(
FindDeclInModules(context, name);
}

if (!context.m_found_type) {
if (!context.m_found_type && m_ast_context->getLangOpts().ObjC) {
FindDeclInObjCRuntime(context, name);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,11 @@ def test(self):
(_, process, _, _) = lldbutil.run_to_name_breakpoint(self, "main")

self.assertState(process.GetState(), lldb.eStateStopped)

# Tests that we can use builtin Objective-C identifiers.
self.expect("expr id", error=False)

# Tests that we can lookup Objective-C decls in the ObjC runtime plugin.
self.expect_expr(
"NSString *c; c == nullptr", result_value="true", result_type="bool"
)
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ def test_early_process_launch(self):
logfile_early = os.path.join(self.getBuildDir(), "types-log-early.txt")
self.addTearDownHook(lambda: self.runCmd("log disable lldb types"))
self.runCmd("log enable -f %s lldb types" % logfile_early)
self.runCmd("expression global = 15")
self.runCmd("expression --language objc -- global = 15")

err = process.Continue()
self.assertTrue(err.Success())

logfile_later = os.path.join(self.getBuildDir(), "types-log-later.txt")
self.runCmd("log enable -f %s lldb types" % logfile_later)
self.runCmd("expression global = 25")
self.runCmd("expression --language objc -- global = 25")

self.assertTrue(os.path.exists(logfile_early))
self.assertTrue(os.path.exists(logfile_later))
Expand Down
21 changes: 21 additions & 0 deletions lldb/test/Shell/Expr/TestObjCInCXXContext.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// UNSUPPORTED: system-linux, system-windows

// Tests that we don't consult the the Objective-C runtime
// plugin when in a purely C++ context.
//
// RUN: %clangxx_host %p/Inputs/objc-cast.cpp -g -o %t
// RUN: %lldb %t \
// RUN: -o "b main" -o run \
// RUN: -o "expression --language objective-c -- NSString * a; a" \
// RUN: -o "expression --language objective-c++ -- NSString * b; b" \
// RUN: -o "expression NSString" \
// RUN: 2>&1 | FileCheck %s

// CHECK: (lldb) expression --language objective-c -- NSString * a; a
// CHECK-NEXT: (NSString *){{.*}}= nil

// CHECK: (lldb) expression --language objective-c++ -- NSString * b; b
// CHECK-NEXT: (NSString *){{.*}}= nil

// CHECK: (lldb) expression NSString
// CHECK-NEXT: error:{{.*}} use of undeclared identifier 'NSString'

0 comments on commit 9e6ea38

Please sign in to comment.