Skip to content

Commit 1d54081

Browse files
committed
Create non-null typerefs in field descriptors for Clang types.
rdar://121758809
1 parent b57791e commit 1d54081

File tree

11 files changed

+116
-9
lines changed

11 files changed

+116
-9
lines changed

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ class LLDBTypeInfoProvider : public swift::remote::TypeInfoProvider {
353353
ExecutionContext exe_ctx;
354354
process.CalculateExecutionContext(exe_ctx);
355355
auto *exe_scope = exe_ctx.GetBestExecutionContextScope();
356+
TypeSystemSwiftTypeRef &typesystem = *m_reader->get();
356357
// Build a TypeInfo for the Clang type.
357358
auto size = clang_type.GetByteSize(exe_scope);
358359
auto bit_align = clang_type.GetTypeBitAlign(exe_scope);
@@ -372,11 +373,14 @@ class LLDBTypeInfoProvider : public swift::remote::TypeInfoProvider {
372373
"[LLDBTypeInfoProvider] bitfield support is not yet implemented");
373374
continue;
374375
}
376+
CompilerType swift_type =
377+
typesystem.ConvertClangTypeToSwiftType(field_type);
378+
auto *typeref = m_runtime.GetTypeRef(swift_type, &typesystem);
375379
swift::reflection::FieldInfo field_info = {
376-
name, (unsigned)bit_offset_ptr / 8, 0, nullptr,
380+
name, (unsigned)bit_offset_ptr / 8, 0, typeref,
377381
*GetOrCreateTypeInfo(field_type)};
378382
fields.push_back(field_info);
379-
}
383+
}
380384
}
381385
return m_runtime.emplaceClangTypeInfo(clang_type, size, bit_align, fields);
382386
}

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,10 @@ class SwiftLanguageRuntimeImpl {
197197

198198
bool IsABIStable();
199199

200+
/// Use the reflection context to build a TypeRef object.
201+
const swift::reflection::TypeRef *
202+
GetTypeRef(CompilerType type, TypeSystemSwiftTypeRef *module_holder);
203+
200204
void DumpTyperef(CompilerType type, TypeSystemSwiftTypeRef *module_holder,
201205
Stream *s);
202206

@@ -212,10 +216,6 @@ class SwiftLanguageRuntimeImpl {
212216
SwiftLanguageRuntime::ForEachGenericParameter(node, callback);
213217
}
214218

215-
/// Use the reflection context to build a TypeRef object.
216-
const swift::reflection::TypeRef *
217-
GetTypeRef(CompilerType type, TypeSystemSwiftTypeRef *module_holder);
218-
219219
/// If \p instance points to a Swift object, retrieve its
220220
/// RecordTypeInfo and pass it to the callback \p fn. Repeat the
221221
/// process with all superclasses. If \p fn returns \p true, early

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

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646

4747
#include <algorithm>
4848
#include <sstream>
49+
#include <type_traits>
4950

5051
using namespace lldb;
5152
using namespace lldb_private;
@@ -330,6 +331,8 @@ TypeSystemSwiftTypeRef::GetClangTypeNode(CompilerType clang_type,
330331
return optional;
331332
}
332333
}
334+
if (clang_type.IsAnonymousType())
335+
return nullptr;
333336
llvm::StringRef clang_name = clang_type.GetTypeName().GetStringRef();
334337
#define MAP_TYPE(C_TYPE_NAME, C_TYPE_KIND, C_TYPE_BITWIDTH, SWIFT_MODULE_NAME, \
335338
SWIFT_TYPE_NAME, CAN_BE_MISSING, C_NAME_MAPPING) \
@@ -382,6 +385,8 @@ TypeSystemSwiftTypeRef::GetClangTypeNode(CompilerType clang_type,
382385
auto *tuple = dem.createNode(Node::Kind::Tuple);
383386
NodePointer element_type = GetClangTypeNode(
384387
{clang_type.GetTypeSystem(), elem_type.getAsOpaquePtr()}, dem);
388+
if (!element_type)
389+
return nullptr;
385390
for (unsigned i = 0; i < size; ++i) {
386391
NodePointer tuple_element = dem.createNode(Node::Kind::TupleElement);
387392
NodePointer type = dem.createNode(Node::Kind::Type);
@@ -413,6 +418,8 @@ TypeSystemSwiftTypeRef::GetClangTypeNode(CompilerType clang_type,
413418
break;
414419

415420
NodePointer element_type_node = GetClangTypeNode(element_type, dem);
421+
if (!element_type_node)
422+
return nullptr;
416423
llvm::SmallVector<NodePointer, 1> elements({element_type_node});
417424
return CreateBoundGenericStruct("SIMD" + std::to_string(size),
418425
swift::STDLIB_NAME, elements, dem);
@@ -818,8 +825,12 @@ TypeSystemSwiftTypeRef::GetCanonicalNode(swift::Demangle::Demangler &dem,
818825
case Node::Kind::BoundGenericTypeAlias:
819826
case Node::Kind::TypeAlias: {
820827
auto node_clangtype = ResolveTypeAlias(dem, node);
821-
if (CompilerType clang_type = node_clangtype.second)
822-
return GetClangTypeNode(clang_type, dem);
828+
if (CompilerType clang_type = node_clangtype.second) {
829+
if (auto result = GetClangTypeNode(clang_type, dem))
830+
return result;
831+
else
832+
return node;
833+
}
823834
if (node_clangtype.first)
824835
return node_clangtype.first;
825836
return node;
@@ -3180,8 +3191,11 @@ TypeSystemSwiftTypeRef::GetClangTypeTypeNode(swift::Demangle::Demangler &dem,
31803191
assert(clang_type.GetTypeSystem().isa_and_nonnull<TypeSystemClang>() &&
31813192
"expected a clang type");
31823193
using namespace swift::Demangle;
3194+
NodePointer node = GetClangTypeNode(clang_type, dem);
3195+
if (!node)
3196+
return nullptr;
31833197
NodePointer type = dem.createNode(Node::Kind::Type);
3184-
type->addChild(GetClangTypeNode(clang_type, dem), dem);
3198+
type->addChild(node, dem);
31853199
return type;
31863200
}
31873201

@@ -3358,6 +3372,8 @@ CompilerType TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex(
33583372
swift::Demangle::Demangler dem;
33593373
swift::Demangle::NodePointer node =
33603374
GetClangTypeTypeNode(dem, clang_child_type);
3375+
if (!node)
3376+
return {};
33613377
switch (node->getChild(0)->getKind()) {
33623378
case swift::Demangle::Node::Kind::Class:
33633379
prefix = "ObjectiveC.";
@@ -3440,6 +3456,7 @@ CompilerType TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex(
34403456
ast_child_name = suffix.str();
34413457
assert((llvm::StringRef(child_name).contains('.') ||
34423458
llvm::StringRef(ast_child_name).contains('.') ||
3459+
llvm::StringRef(ast_child_name).starts_with("_") ||
34433460
Equivalent(child_name, ast_child_name)));
34443461
assert(ast_language_flags ||
34453462
(Equivalent(std::optional<uint64_t>(child_byte_size),
@@ -4457,6 +4474,8 @@ TypeSystemSwiftTypeRef::GetTypedefedType(opaque_compiler_type_t type) {
44574474
} else {
44584475
NodePointer clang_node =
44594476
GetClangTypeNode(std::get<CompilerType>(pair), dem);
4477+
if (!clang_node)
4478+
return {};
44604479
type_node->addChild(clang_node, dem);
44614480
}
44624481
return RemangleAsType(dem, type_node);

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift {
398398

399399
/// Lookup a type in the debug info.
400400
lldb::TypeSP FindTypeInModule(lldb::opaque_compiler_type_t type);
401+
401402
protected:
402403
/// Helper that creates an AST type from \p type.
403404
void *ReconstructType(lldb::opaque_compiler_type_t type,
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
struct FromClang {
2+
int x;
3+
};
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
struct FromClang {
2+
int x;
3+
};
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# This Makefile recursively calls itself, hence the ?=.
2+
EXE ?= a.out
3+
SWIFT_SOURCES ?= loader.swift
4+
SWIFT_BRIDGING_HEADER ?= ClangHeader.h
5+
SWIFT_PRECOMPILE_BRIDGING_HEADER ?= NO
6+
SWIFTFLAGS_EXTRAS ?= -enable-bare-slash-regex
7+
8+
all: dylib $(EXE)
9+
10+
include Makefile.rules
11+
12+
.PHONY: dylib
13+
dylib:
14+
$(MAKE) MAKE_DSYM=$(MAKE_DSYM) CC=$(CC) SWIFTC=$(SWIFTC) \
15+
ARCH=$(ARCH) DSYMUTIL=$(DSYMUTIL) \
16+
VPATH=$(SRCDIR) -I $(SRCDIR) \
17+
-f $(SRCDIR)/Makefile \
18+
DYLIB_FILENAME=dylib.dylib \
19+
DYLIB_SWIFT_SOURCES=dylib.swift \
20+
DYLIB_NAME=dylib \
21+
DYLIB_ONLY=YES \
22+
SWIFTFLAGS_EXTRAS="-Xcc -I$(SRCDIR)" \
23+
SWIFT_SOURCES= \
24+
SWIFT_BRIDGING_HEADER= \
25+
LD_EXTRAS="-lSwiftCore -Xlinker -exported_symbol -Xlinker _f" \
26+
dylib.dylib
27+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from lldbsuite.test.lldbtest import *
2+
from lldbsuite.test.decorators import *
3+
import lldbsuite.test.lldbutil as lldbutil
4+
5+
class TestSwiftLateSwiftDylibClangDeps(TestBase):
6+
@skipUnlessDarwin
7+
@swiftTest
8+
@skipIfDarwinEmbedded
9+
def test(self):
10+
"""Test that the reflection metadata cache is invalidated
11+
when new DWARF debug info is available"""
12+
self.build()
13+
target, process, _, _ = lldbutil.run_to_source_breakpoint(
14+
self, "break here", lldb.SBFileSpec("loader.swift"))
15+
16+
# Initialize SwiftASTContext before loading the dylib.
17+
self.runCmd("setting set symbols.swift-enable-ast-context false")
18+
self.expect("v fromClang",
19+
substrs=["missing debug info", "FromClang"])
20+
21+
bkpt = target.BreakpointCreateByLocation(
22+
lldb.SBFileSpec('dylib.swift'), 5)
23+
threads = lldbutil.continue_to_breakpoint(process, bkpt)
24+
25+
self.expect("v x", substrs=['42'])
26+
self.expect("frame select 1")
27+
self.expect("v fromClang", substrs=['23'])
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import ClangMod
2+
3+
@_silgen_name("f") public func f() {
4+
let x = FromClang(x: 42)
5+
print(x) // line 5
6+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import Darwin
2+
3+
// This lookup should fail in debugger.
4+
let fromClang = FromClang(x: 23)
5+
print(fromClang) // break here
6+
7+
// Now load the dylib.
8+
let arg0 = CommandLine.arguments[0]
9+
let dylibName = arg0.replacing(/a\.out$/, with: "dylib.dylib")
10+
let dylib = dlopen(dylibName, Darwin.RTLD_NOW)
11+
let fsym = dlsym(dylib!, "f")
12+
typealias voidTy = @convention(c) () -> ()
13+
let f = unsafeBitCast(fsym, to: voidTy.self)
14+
f()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module ClangMod {
2+
header "ClangMod.h"
3+
}

0 commit comments

Comments
 (0)