Skip to content

Commit 74fe8ae

Browse files
authored
Merge pull request #11648 from swiftlang/lldb/valueobject-objc-lookup-refactor-to-21.x
[lldb][ValueObject] Move Objective-C specific lookups into ObjCLanguageRuntime
2 parents 1179e0c + 1152cf1 commit 74fe8ae

File tree

8 files changed

+139
-68
lines changed

8 files changed

+139
-68
lines changed

lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,46 @@ Status ObjCLanguageRuntime::ObjCExceptionPrecondition::ConfigurePrecondition(
423423
return error;
424424
}
425425

426+
CompilerType ObjCLanguageRuntime::LookupInModulesVendor(ConstString class_name,
427+
Target &target) {
428+
assert(class_name);
429+
430+
auto *persistent_state = llvm::cast<ClangPersistentVariables>(
431+
target.GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC));
432+
if (!persistent_state)
433+
return {};
434+
435+
auto clang_modules_decl_vendor_sp =
436+
persistent_state->GetClangModulesDeclVendor();
437+
if (!clang_modules_decl_vendor_sp)
438+
return {};
439+
440+
auto types = clang_modules_decl_vendor_sp->FindTypes(
441+
class_name, /*max_matches*/ UINT32_MAX);
442+
if (types.empty())
443+
return {};
444+
445+
return types.front();
446+
}
447+
448+
CompilerType ObjCLanguageRuntime::LookupInRuntime(ConstString class_name) {
449+
auto *runtime_vendor = GetDeclVendor();
450+
if (!runtime_vendor)
451+
return {};
452+
453+
std::vector<CompilerDecl> compiler_decls;
454+
runtime_vendor->FindDecls(class_name, false, UINT32_MAX, compiler_decls);
455+
if (compiler_decls.empty())
456+
return {};
457+
458+
auto *ctx =
459+
llvm::dyn_cast<TypeSystemClang>(compiler_decls[0].GetTypeSystem());
460+
if (!ctx)
461+
return {};
462+
463+
return ctx->GetTypeForDecl(compiler_decls[0].GetOpaqueDecl());
464+
}
465+
426466
std::optional<CompilerType>
427467
ObjCLanguageRuntime::GetRuntimeType(CompilerType base_type) {
428468
CompilerType class_type;
@@ -442,18 +482,21 @@ ObjCLanguageRuntime::GetRuntimeType(CompilerType base_type) {
442482
if (!class_name)
443483
return std::nullopt;
444484

445-
TypeSP complete_objc_class_type_sp = LookupInCompleteClassCache(class_name);
446-
if (!complete_objc_class_type_sp)
447-
return std::nullopt;
448-
449-
CompilerType complete_class(
450-
complete_objc_class_type_sp->GetFullCompilerType());
451-
if (complete_class.GetCompleteType()) {
452-
if (is_pointer_type)
453-
return complete_class.GetPointerType();
454-
else
455-
return complete_class;
485+
if (TypeSP complete_objc_class_type_sp =
486+
LookupInCompleteClassCache(class_name)) {
487+
if (CompilerType complete_class =
488+
complete_objc_class_type_sp->GetFullCompilerType();
489+
complete_class.GetCompleteType())
490+
return is_pointer_type ? complete_class.GetPointerType() : complete_class;
456491
}
457492

493+
assert(m_process);
494+
if (CompilerType found =
495+
LookupInModulesVendor(class_name, m_process->GetTarget()))
496+
return is_pointer_type ? found.GetPointerType() : found;
497+
498+
if (CompilerType found = LookupInRuntime(class_name))
499+
return is_pointer_type ? found.GetPointerType() : found;
500+
458501
return std::nullopt;
459502
}

lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,10 @@ class ObjCLanguageRuntime : public LanguageRuntime {
465465

466466
ObjCLanguageRuntime(const ObjCLanguageRuntime &) = delete;
467467
const ObjCLanguageRuntime &operator=(const ObjCLanguageRuntime &) = delete;
468+
469+
private:
470+
CompilerType LookupInRuntime(ConstString class_name);
471+
CompilerType LookupInModulesVendor(ConstString class_name, Target &process);
468472
};
469473

470474
} // namespace lldb_private

lldb/source/ValueObject/ValueObject.cpp

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -277,63 +277,6 @@ CompilerType ValueObject::MaybeCalculateCompleteType() {
277277
}
278278
}
279279

280-
std::vector<clang::NamedDecl *> decls;
281-
CompilerType class_type;
282-
bool is_pointer_type = false;
283-
if (TypeSystemClang::IsObjCObjectPointerType(compiler_type, &class_type))
284-
is_pointer_type = true;
285-
else if (TypeSystemClang::IsObjCObjectOrInterfaceType(compiler_type))
286-
class_type = compiler_type;
287-
else
288-
return compiler_type;
289-
290-
ConstString class_name(class_type.GetTypeName());
291-
if (!class_name)
292-
return compiler_type;
293-
294-
// try the modules
295-
if (TargetSP target_sp = GetTargetSP()) {
296-
auto *persistent_state = llvm::cast<ClangPersistentVariables>(
297-
target_sp->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC));
298-
if (!persistent_state)
299-
return compiler_type;
300-
301-
if (auto clang_modules_decl_vendor =
302-
persistent_state->GetClangModulesDeclVendor()) {
303-
ConstString key_cs(class_name);
304-
auto types = clang_modules_decl_vendor->FindTypes(
305-
key_cs, /*max_matches*/ UINT32_MAX);
306-
if (!types.empty()) {
307-
auto module_type = types.front();
308-
m_override_type =
309-
is_pointer_type ? module_type.GetPointerType() : module_type;
310-
}
311-
312-
if (m_override_type.IsValid())
313-
return m_override_type;
314-
}
315-
}
316-
317-
// then try the runtime
318-
if (auto *objc_language_runtime = ObjCLanguageRuntime::Get(*process_sp)) {
319-
if (auto *runtime_vendor = objc_language_runtime->GetDeclVendor()) {
320-
std::vector<CompilerDecl> compiler_decls;
321-
runtime_vendor->FindDecls(class_name, false, UINT32_MAX, compiler_decls);
322-
if (!compiler_decls.empty()) {
323-
auto *ctx =
324-
llvm::dyn_cast<TypeSystemClang>(compiler_decls[0].GetTypeSystem());
325-
if (ctx) {
326-
CompilerType runtime_type =
327-
ctx->GetTypeForDecl(compiler_decls[0].GetOpaqueDecl());
328-
m_override_type =
329-
is_pointer_type ? runtime_type.GetPointerType() : runtime_type;
330-
}
331-
}
332-
333-
if (m_override_type.IsValid())
334-
return m_override_type;
335-
}
336-
}
337280
return compiler_type;
338281
}
339282

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
OBJC_SOURCES := main.m lib.m
2+
LD_EXTRAS = -framework Foundation
3+
4+
include Makefile.rules
5+
6+
lib.o: CFLAGS = $(CFLAGS_NO_DEBUG)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import lldb
2+
from lldbsuite.test.decorators import *
3+
from lldbsuite.test.lldbtest import *
4+
from lldbsuite.test import lldbutil
5+
6+
7+
class TestIvarInFrameworkBase(TestBase):
8+
"""
9+
Tests whether LLDB's data inspection commands can correctly retrieve
10+
information about ivars from the Objective-C runtime.
11+
In this test-case we have a base class type for which we don't have access
12+
to the debug-info of the implementation (mimicking the scenario of subclassing
13+
a type from a system framework). LLDB won't be able to see the backing ivar for
14+
'fooProp' from just debug-info, but it will fall back on the runtime to get the
15+
necessary information.
16+
"""
17+
18+
def test_frame_var(self):
19+
self.build()
20+
lldbutil.run_to_source_breakpoint(self, "break here", lldb.SBFileSpec("main.m"))
21+
self.expect("frame variable *bar", substrs=["_fooProp = 10", "_barProp = 15"])
22+
23+
def test_expr(self):
24+
self.build()
25+
lldbutil.run_to_source_breakpoint(self, "break here", lldb.SBFileSpec("main.m"))
26+
self.expect_expr(
27+
"*bar",
28+
result_type="Bar",
29+
result_children=[
30+
ValueCheck(
31+
name="Foo",
32+
children=[
33+
ValueCheck(name="NSObject"),
34+
ValueCheck(name="_fooProp", value="10"),
35+
],
36+
),
37+
ValueCheck(name="_barProp", value="15"),
38+
],
39+
)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#import <Foundation/Foundation.h>
2+
3+
@interface Foo : NSObject
4+
@property int fooProp;
5+
- (id)init;
6+
@end
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#import "lib.h"
2+
3+
@implementation Foo
4+
- (id)init {
5+
self.fooProp = 10;
6+
return self;
7+
}
8+
@end
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#import "lib.h"
2+
#include <stdio.h>
3+
4+
@interface Bar : Foo
5+
@property int barProp;
6+
- (id)init;
7+
@end
8+
9+
@implementation Bar
10+
11+
- (id)init {
12+
self = [super init];
13+
self.barProp = 15;
14+
return self;
15+
}
16+
@end
17+
18+
int main() {
19+
Bar *bar = [Bar new];
20+
puts("break here");
21+
return 0;
22+
}

0 commit comments

Comments
 (0)