Skip to content

Commit 7d0518c

Browse files
Merge pull request #8490 from adrian-prantl/anonymous-types
[LLDBTypeInfoProvider] Store anonymous clang types in a side table
2 parents 588dd92 + 851bb55 commit 7d0518c

File tree

5 files changed

+96
-28
lines changed

5 files changed

+96
-28
lines changed

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -331,9 +331,12 @@ class LLDBTypeInfoProvider : public swift::remote::TypeInfoProvider {
331331
auto ts = swift_type.GetTypeSystem().dyn_cast_or_null<TypeSystemSwift>();
332332
if (!ts)
333333
return nullptr;
334-
CompilerType clang_type;
335-
bool is_imported =
336-
ts->IsImportedType(swift_type.GetOpaqueQualType(), &clang_type);
334+
bool is_imported = true;
335+
CompilerType clang_type =
336+
m_runtime.LookupAnonymousClangType(mangled.AsCString());
337+
if (!clang_type)
338+
is_imported =
339+
ts->IsImportedType(swift_type.GetOpaqueQualType(), &clang_type);
337340
if (!is_imported || !clang_type) {
338341
HEALTH_LOG("[LLDBTypeInfoProvider] Could not find clang debug type info "
339342
"for {0}",
@@ -373,8 +376,20 @@ class LLDBTypeInfoProvider : public swift::remote::TypeInfoProvider {
373376
"[LLDBTypeInfoProvider] bitfield support is not yet implemented");
374377
continue;
375378
}
376-
CompilerType swift_type =
377-
typesystem.ConvertClangTypeToSwiftType(field_type);
379+
CompilerType swift_type;
380+
if (field_type.IsAnonymousType()) {
381+
// Store anonymous tuples in a side table, to solve the
382+
// problem that they cannot be looked up by name.
383+
static unsigned m_num_anonymous_clang_types = 0;
384+
std::string unique_swift_name(field_type.GetTypeName());
385+
llvm::raw_string_ostream(unique_swift_name)
386+
<< '#' << m_num_anonymous_clang_types++;
387+
swift_type = typesystem.CreateClangStructType(unique_swift_name);
388+
auto *key = swift_type.GetMangledTypeName().AsCString();
389+
m_runtime.RegisterAnonymousClangType(key, field_type);
390+
} else {
391+
swift_type = typesystem.ConvertClangTypeToSwiftType(field_type);
392+
}
378393
auto *typeref = m_runtime.GetTypeRef(swift_type, &typesystem);
379394
swift::reflection::FieldInfo field_info = {
380395
name, (unsigned)bit_offset_ptr / 8, 0, typeref,
@@ -386,6 +401,18 @@ class LLDBTypeInfoProvider : public swift::remote::TypeInfoProvider {
386401
}
387402
};
388403

404+
void SwiftLanguageRuntimeImpl::RegisterAnonymousClangType(
405+
const char *key, CompilerType clang_type) {
406+
const std::lock_guard<std::recursive_mutex> locker(m_clang_type_info_mutex);
407+
m_anonymous_clang_types.insert({key, clang_type});
408+
}
409+
410+
CompilerType
411+
SwiftLanguageRuntimeImpl::LookupAnonymousClangType(const char *key) {
412+
const std::lock_guard<std::recursive_mutex> locker(m_clang_type_info_mutex);
413+
return m_anonymous_clang_types.lookup(key);
414+
}
415+
389416
std::optional<const swift::reflection::TypeInfo *>
390417
SwiftLanguageRuntimeImpl::lookupClangTypeInfo(CompilerType clang_type) {
391418
std::lock_guard<std::recursive_mutex> locker(m_clang_type_info_mutex);

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@ class SwiftLanguageRuntimeImpl {
170170
CompilerType BindGenericTypeParameters(StackFrame &stack_frame,
171171
CompilerType base_type);
172172

173+
/// Enter an anonymous Clang type with a name key into a side table.
174+
void RegisterAnonymousClangType(const char *key, CompilerType clang_type);
175+
/// Look up an anonymous Clang type with a name key into a side table.
176+
CompilerType LookupAnonymousClangType(const char *key);
177+
173178
CompilerType GetConcreteType(ExecutionContextScope *exe_scope,
174179
ConstString abstract_type_name);
175180

@@ -434,6 +439,8 @@ class SwiftLanguageRuntimeImpl {
434439
llvm::DenseMap<lldb::opaque_compiler_type_t,
435440
std::optional<swift::reflection::RecordTypeInfo>>
436441
m_clang_record_type_info;
442+
llvm::DenseMap<const char *, CompilerType> m_anonymous_clang_types;
443+
unsigned m_num_anonymous_clang_types = 0;
437444
std::recursive_mutex m_clang_type_info_mutex;
438445
/// \}
439446

lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,22 @@ NodePointer TypeSystemSwiftTypeRef::CreateBoundGenericStruct(
321321
return outer_type;
322322
}
323323

324+
CompilerType
325+
TypeSystemSwiftTypeRef::CreateClangStructType(llvm::StringRef name) {
326+
using namespace swift::Demangle;
327+
Demangler dem;
328+
NodePointer module = dem.createNodeWithAllocatedText(
329+
Node::Kind::Module, swift::MANGLING_MODULE_OBJC);
330+
NodePointer identifier =
331+
dem.createNodeWithAllocatedText(Node::Kind::Identifier, name);
332+
NodePointer nominal = dem.createNode(Node::Kind::Structure);
333+
nominal->addChild(module, dem);
334+
nominal->addChild(identifier, dem);
335+
NodePointer type = dem.createNode(Node::Kind::Type);
336+
type->addChild(nominal, dem);
337+
return RemangleAsType(dem, type);
338+
}
339+
324340
/// Return a demangle tree leaf node representing \p clang_type.
325341
swift::Demangle::NodePointer
326342
TypeSystemSwiftTypeRef::GetClangTypeNode(CompilerType clang_type,

lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,9 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift {
327327
CompilerType CreateGenericTypeParamType(unsigned int depth,
328328
unsigned int index) override;
329329

330+
/// Create a __C imported struct type.
331+
CompilerType CreateClangStructType(llvm::StringRef name);
332+
330333
/// Builds a bound generic struct demangle tree with the name, module name,
331334
/// and the struct's elements.
332335
static swift::Demangle::NodePointer CreateBoundGenericStruct(

lldb/test/API/lang/swift/clangimporter/anonymous-clang-types/TestSwiftAnonymousClangTypes.py

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,48 @@
66

77
class TestSwiftAnonymousClangTypes(lldbtest.TestBase):
88
@swiftTest
9-
# FIMXE: This broke when adapting the swift-driver based Makefile.rules
9+
# FIXME: This broke when adapting the swift-driver based Makefile.rules
1010
@expectedFailureAll(oslist=['linux'])
1111
def test(self):
1212
self.build()
1313

14-
lldbutil.run_to_source_breakpoint(
14+
target, _, _, _ = lldbutil.run_to_source_breakpoint(
1515
self, "break here", lldb.SBFileSpec("main.swift")
1616
)
17-
self.expect(
18-
"frame variable twoStructs",
19-
substrs=[
20-
"(TwoAnonymousStructs) twoStructs = {",
21-
"= (x = 1, y = 2, z = 3)",
22-
"= (a = 4)",
23-
],
24-
)
17+
def check(field, value):
18+
self.assertTrue(field.IsValid())
19+
lldbutil.check_variable(self, field, False, value=value)
2520

26-
self.expect(
27-
"frame variable twoUnions",
28-
substrs=[
29-
"(TwoAnonymousUnions) twoUnions = {",
30-
" = {",
31-
" = (x = 2)",
32-
" = (y = 2, z = 3)",
33-
" }",
34-
" = {",
35-
" = (a = 4, b = 5, c = 6)",
36-
" = (d = 4, e = 5)",
37-
],
38-
)
21+
twoStructs = target.FindFirstGlobalVariable("twoStructs")
22+
self.assertTrue(twoStructs.IsValid())
23+
24+
field0 = twoStructs.GetChildAtIndex(0)
25+
self.assertTrue(field0.IsValid())
26+
check(field0.GetChildMemberWithName("x"), value="1")
27+
check(field0.GetChildMemberWithName("y"), value="2")
28+
check(field0.GetChildMemberWithName("z"), value="3")
29+
30+
field1 = twoStructs.GetChildAtIndex(1)
31+
self.assertTrue(field1.IsValid())
32+
check(field1.GetChildMemberWithName("a"), value="4")
33+
34+
35+
twoUnions = target.FindFirstGlobalVariable("twoUnions")
36+
self.assertTrue(twoUnions.IsValid())
37+
field0 = twoUnions.GetChildAtIndex(0)
38+
self.assertTrue(field0.IsValid())
39+
field0_0 = field0.GetChildAtIndex(0)
40+
check(field0_0.GetChildMemberWithName("x"), value="2")
41+
field0_1 = field0.GetChildAtIndex(1)
42+
check(field0_1.GetChildMemberWithName("y"), value="2")
43+
check(field0_1.GetChildMemberWithName("z"), value="3")
44+
45+
field1 = twoUnions.GetChildAtIndex(1)
46+
self.assertTrue(field1.IsValid())
47+
field1_0 = field1.GetChildAtIndex(0)
48+
check(field1_0.GetChildMemberWithName("a"), value="4")
49+
check(field1_0.GetChildMemberWithName("b"), value="5")
50+
check(field1_0.GetChildMemberWithName("c"), value="6")
51+
field1_1 = field1.GetChildAtIndex(1)
52+
check(field1_1.GetChildMemberWithName("d"), value="4")
53+
check(field1_1.GetChildMemberWithName("e"), value="5")

0 commit comments

Comments
 (0)