Skip to content

Commit 0533d20

Browse files
Merge pull request #11486 from adrian-prantl/159429896-6.2
Support Swift.Array in Embedded Swift
2 parents 4b956de + 9fd1719 commit 0533d20

File tree

9 files changed

+519
-115
lines changed

9 files changed

+519
-115
lines changed

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

Lines changed: 65 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "LLDBMemoryReader.h"
14+
#include "Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h"
1415
#include "ReflectionContextInterface.h"
1516
#include "SwiftLanguageRuntime.h"
1617
#include "SwiftMetadataCache.h"
@@ -607,13 +608,14 @@ std::optional<uint64_t> SwiftLanguageRuntime::GetMemberVariableOffset(
607608
namespace {
608609

609610
CompilerType GetTypeFromTypeRef(TypeSystemSwiftTypeRef &ts,
610-
const swift::reflection::TypeRef *type_ref) {
611+
const swift::reflection::TypeRef *type_ref,
612+
swift::Mangle::ManglingFlavor flavor) {
611613
if (!type_ref)
612614
return {};
613615
swift::Demangle::Demangler dem;
614616
swift::Demangle::NodePointer node = type_ref->getDemangling(dem);
615617
// TODO: the mangling flavor should come from the TypeRef.
616-
return ts.RemangleAsType(dem, node, ts.GetManglingFlavor());
618+
return ts.RemangleAsType(dem, node, flavor);
617619
}
618620

619621
struct ExistentialSyntheticChild {
@@ -627,7 +629,8 @@ struct ExistentialSyntheticChild {
627629
llvm::SmallVector<ExistentialSyntheticChild, 4>
628630
GetExistentialSyntheticChildren(TypeSystemSwiftTypeRef &ts,
629631
const swift::reflection::TypeRef *tr,
630-
const swift::reflection::TypeInfo *ti) {
632+
const swift::reflection::TypeInfo *ti,
633+
swift::Mangle::ManglingFlavor flavor) {
631634
llvm::SmallVector<ExistentialSyntheticChild, 4> children;
632635
auto *protocol_composition_tr =
633636
llvm::dyn_cast<swift::reflection::ProtocolCompositionTypeRef>(tr);
@@ -641,7 +644,8 @@ GetExistentialSyntheticChildren(TypeSystemSwiftTypeRef &ts,
641644
children.push_back({"object", [=]() {
642645
if (auto *super_class_tr =
643646
protocol_composition_tr->getSuperclass())
644-
return GetTypeFromTypeRef(*ts_sp, super_class_tr);
647+
return GetTypeFromTypeRef(*ts_sp, super_class_tr,
648+
flavor);
645649
else
646650
return rti ? ts_sp->GetBuiltinUnknownObjectType()
647651
: ts_sp->GetBuiltinRawPointerType();
@@ -652,9 +656,9 @@ GetExistentialSyntheticChildren(TypeSystemSwiftTypeRef &ts,
652656
for (unsigned i = 1; i < fields.size(); ++i) {
653657
TypeSystemSwiftTypeRefSP ts_sp = ts.GetTypeSystemSwiftTypeRef();
654658
auto *type_ref = fields[i].TR;
655-
children.push_back({fields[i].Name, [=]() {
656-
return GetTypeFromTypeRef(*ts_sp, type_ref);
657-
}});
659+
children.push_back(
660+
{fields[i].Name,
661+
[=]() { return GetTypeFromTypeRef(*ts_sp, type_ref, flavor); }});
658662
}
659663
}
660664
}
@@ -702,12 +706,20 @@ CompilerType GetTypedefedTypeRecursive(CompilerType type) {
702706
class SwiftRuntimeTypeVisitor {
703707
SwiftLanguageRuntime &m_runtime;
704708
ExecutionContext m_exe_ctx;
709+
swift::Mangle::ManglingFlavor m_flavor =
710+
swift::Mangle::ManglingFlavor::Default;
705711
CompilerType m_type;
706712
ValueObject *m_valobj = nullptr;
707713
bool m_hide_superclass = false;
708714
bool m_include_clang_types = false;
709715
bool m_visit_superclass = false;
710716

717+
void SetFlavor() {
718+
if (auto ts_sp =
719+
m_type.GetTypeSystem().dyn_cast_or_null<TypeSystemSwiftTypeRef>())
720+
m_flavor = ts_sp->GetManglingFlavor(&m_exe_ctx);
721+
}
722+
711723
public:
712724
struct ChildInfo {
713725
uint32_t byte_size = 0;
@@ -732,6 +744,7 @@ class SwiftRuntimeTypeVisitor {
732744
: m_runtime(runtime), m_type(type), m_valobj(valobj) {
733745
if (valobj)
734746
m_exe_ctx = valobj->GetExecutionContextRef();
747+
SetFlavor();
735748
}
736749
SwiftRuntimeTypeVisitor(SwiftLanguageRuntime &runtime, CompilerType type,
737750
ExecutionContextScope *exe_scope,
@@ -740,6 +753,7 @@ class SwiftRuntimeTypeVisitor {
740753
m_include_clang_types(include_clang_types) {
741754
if (exe_scope)
742755
exe_scope->CalculateExecutionContext(m_exe_ctx);
756+
SetFlavor();
743757
}
744758
SwiftRuntimeTypeVisitor(SwiftLanguageRuntime &runtime, CompilerType type,
745759
ExecutionContext *exe_ctx, bool hide_superclass,
@@ -749,6 +763,7 @@ class SwiftRuntimeTypeVisitor {
749763
m_visit_superclass(visit_superclass) {
750764
if (exe_ctx)
751765
m_exe_ctx = *exe_ctx;
766+
SetFlavor();
752767
}
753768
llvm::Error VisitAllChildren(VisitCallback callback) {
754769
return VisitImpl({}, callback).takeError();
@@ -871,7 +886,7 @@ SwiftRuntimeTypeVisitor::VisitImpl(std::optional<unsigned> visit_only,
871886
field_type = tuple->element_type;
872887
else {
873888
if (!field_type)
874-
field_type = GetTypeFromTypeRef(ts, field.TR);
889+
field_type = GetTypeFromTypeRef(ts, field.TR, m_flavor);
875890
}
876891
auto get_info = [&]() -> llvm::Expected<ChildInfo> {
877892
ChildInfo child;
@@ -968,7 +983,7 @@ SwiftRuntimeTypeVisitor::VisitImpl(std::optional<unsigned> visit_only,
968983
if (rti->getRecordKind() ==
969984
swift::reflection::RecordKind::ClassExistential) {
970985
// Compatibility with SwiftASTContext.
971-
auto children = GetExistentialSyntheticChildren(ts, tr, ti);
986+
auto children = GetExistentialSyntheticChildren(ts, tr, ti, m_flavor);
972987
if (count_only)
973988
return children.size();
974989
auto visit_existential = [&](ExistentialSyntheticChild c, unsigned idx) {
@@ -1019,7 +1034,7 @@ SwiftRuntimeTypeVisitor::VisitImpl(std::optional<unsigned> visit_only,
10191034
llvm::dyn_cast_or_null<swift::reflection::ReferenceTypeInfo>(ti)) {
10201035
// Is this an Existential?
10211036
unsigned i = 0;
1022-
auto children = GetExistentialSyntheticChildren(ts, tr, ti);
1037+
auto children = GetExistentialSyntheticChildren(ts, tr, ti, m_flavor);
10231038
if (children.size()) {
10241039
if (count_only)
10251040
return children.size();
@@ -1109,7 +1124,7 @@ SwiftRuntimeTypeVisitor::VisitImpl(std::optional<unsigned> visit_only,
11091124
if (auto *super_tr = reflection_ctx->LookupSuperclass(
11101125
*tr, ts.GetDescriptorFinder()))
11111126
if (auto error = visit_callback(
1112-
GetTypeFromTypeRef(ts, super_tr), depth,
1127+
GetTypeFromTypeRef(ts, super_tr, m_flavor), depth,
11131128
[]() -> std::string { return "<base class>"; },
11141129
[]() -> llvm::Expected<ChildInfo> {
11151130
return ChildInfo();
@@ -1143,8 +1158,9 @@ SwiftRuntimeTypeVisitor::VisitImpl(std::optional<unsigned> visit_only,
11431158
return ChildInfo();
11441159
};
11451160

1146-
if (auto error = visit_callback(GetTypeFromTypeRef(ts, super_tr), 0,
1147-
get_name, get_info))
1161+
if (auto error =
1162+
visit_callback(GetTypeFromTypeRef(ts, super_tr, m_flavor), 0,
1163+
get_name, get_info))
11481164
return error;
11491165
}
11501166

@@ -1263,7 +1279,7 @@ SwiftRuntimeTypeVisitor::VisitImpl(std::optional<unsigned> visit_only,
12631279
return success;
12641280
}
12651281

1266-
CompilerType super_type = GetTypeFromTypeRef(ts, type_ref);
1282+
CompilerType super_type = GetTypeFromTypeRef(ts, type_ref, m_flavor);
12671283
auto get_name = [&]() -> std::string {
12681284
auto child_name = super_type.GetTypeName().GetStringRef().str();
12691285
// FIXME: This should be fixed in GetDisplayTypeName instead!
@@ -1471,6 +1487,8 @@ SwiftLanguageRuntime::ProjectEnum(ValueObject &valobj) {
14711487
if (!ti_or_err)
14721488
return ti_or_err.takeError();
14731489
auto *ti = &*ti_or_err;
1490+
auto flavor =
1491+
SwiftLanguageRuntime::GetManglingFlavor(enum_type.GetMangledTypeName());
14741492

14751493
auto project_indirect_enum =
14761494
[&](uint64_t offset, std::string name) -> llvm::Expected<ValueObjectSP> {
@@ -1496,13 +1514,14 @@ SwiftLanguageRuntime::ProjectEnum(ValueObject &valobj) {
14961514
auto &field = rti->getFields()[0];
14971515
auto *type_ref = field.TR;
14981516
payload += field.Offset;
1499-
payload_type = GetTypeFromTypeRef(ts, type_ref);
1517+
payload_type = GetTypeFromTypeRef(ts, type_ref, flavor);
15001518
break;
15011519
}
15021520
case swift::reflection::RecordKind::Tuple: {
15031521
std::vector<TypeSystemSwift::TupleElement> elts;
15041522
for (auto &field : rti->getFields())
1505-
elts.emplace_back(ConstString(), GetTypeFromTypeRef(ts, field.TR));
1523+
elts.emplace_back(ConstString(),
1524+
GetTypeFromTypeRef(ts, field.TR, flavor));
15061525
payload_type = ts.CreateTupleType(elts);
15071526
break;
15081527
}
@@ -1571,7 +1590,7 @@ SwiftLanguageRuntime::ProjectEnum(ValueObject &valobj) {
15711590
if (is_indirect_enum)
15721591
return project_indirect_enum(field_info.Offset, field_info.Name);
15731592

1574-
CompilerType projected_type = GetTypeFromTypeRef(ts, field_info.TR);
1593+
CompilerType projected_type = GetTypeFromTypeRef(ts, field_info.TR, flavor);
15751594
if (field_info.Offset != 0) {
15761595
assert(false);
15771596
return llvm::createStringError("enum with unexpected offset");
@@ -1679,7 +1698,9 @@ CompilerType SwiftLanguageRuntime::GetBaseClass(CompilerType class_ty) {
16791698
}
16801699
auto *super_tr = reflection_ctx->LookupSuperclass(
16811700
*type_ref_or_err, tr_ts->GetDescriptorFinder());
1682-
return GetTypeFromTypeRef(*tr_ts, super_tr);
1701+
auto flavor =
1702+
SwiftLanguageRuntime::GetManglingFlavor(class_ty.GetMangledTypeName());
1703+
return GetTypeFromTypeRef(*tr_ts, super_tr, flavor);
16831704
}
16841705

16851706
bool SwiftLanguageRuntime::ForEachSuperClassType(
@@ -3399,9 +3420,9 @@ SwiftLanguageRuntime::GetSwiftRuntimeTypeInfo(
33993420
// Resolve all generic type parameters in the type for the current
34003421
// frame. Generic parameter binding has to happen in the scratch
34013422
// context.
3423+
ExecutionContext exe_ctx;
34023424
if (exe_scope)
34033425
if (StackFrame *frame = exe_scope->CalculateStackFrame().get()) {
3404-
ExecutionContext exe_ctx;
34053426
frame->CalculateExecutionContext(exe_ctx);
34063427
auto bound_type_or_err = BindGenericTypeParameters(*frame, type);
34073428
if (!bound_type_or_err)
@@ -3423,6 +3444,30 @@ SwiftLanguageRuntime::GetSwiftRuntimeTypeInfo(
34233444
if (!reflection_ctx)
34243445
return llvm::createStringError("no reflection context");
34253446

3447+
// The TypeSystemSwiftTypeRefForExpressions doesn't ve a SymbolFile,
3448+
// so any DWARF lookups for Embedded Swift fail.
3449+
//
3450+
// FIXME: It's unclear whether this is safe to do in a non-LTO Swift program.
3451+
if (llvm::isa<TypeSystemSwiftTypeRefForExpressions>(tr_ts.get()) &&
3452+
tr_ts->GetManglingFlavor(&exe_ctx) ==
3453+
swift::Mangle::ManglingFlavor::Embedded) {
3454+
if (auto frame_sp = exe_ctx.GetFrameSP()) {
3455+
auto &sc = frame_sp->GetSymbolContext(eSymbolContextModule);
3456+
if (sc.module_sp) {
3457+
auto ts_or_err =
3458+
sc.module_sp->GetTypeSystemForLanguage(eLanguageTypeSwift);
3459+
if (!ts_or_err)
3460+
return ts_or_err.takeError();
3461+
if (auto *tr_ts = llvm::dyn_cast_or_null<TypeSystemSwiftTypeRef>(
3462+
ts_or_err->get())) {
3463+
LLDBTypeInfoProvider provider(*this, *tr_ts);
3464+
return reflection_ctx->GetTypeInfo(*type_ref_or_err, &provider,
3465+
tr_ts->GetDescriptorFinder());
3466+
}
3467+
}
3468+
}
3469+
}
3470+
34263471
LLDBTypeInfoProvider provider(*this, ts);
34273472
return reflection_ctx->GetTypeInfo(*type_ref_or_err, &provider,
34283473
tr_ts->GetDescriptorFinder());
@@ -3561,7 +3606,7 @@ SwiftLanguageRuntime::ResolveTypeAlias(CompilerType alias) {
35613606
type_ref = &*type_ref_or_err;
35623607
}
35633608

3564-
CompilerType resolved = GetTypeFromTypeRef(*tr_ts, type_ref);
3609+
CompilerType resolved = GetTypeFromTypeRef(*tr_ts, type_ref, flavor);
35653610
LLDB_LOG(GetLog(LLDBLog::Types),
35663611
"Resolved type alias {0} = {1} using reflection metadata.",
35673612
alias.GetMangledTypeName(), resolved.GetMangledTypeName());

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserSwift.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,9 @@ lldb::TypeSP DWARFASTParserSwift::ParseTypeFromDWARF(const SymbolContext &sc,
173173
if (TypeSP desugared_type = get_type(die)) {
174174
// For a typedef, store the once desugared type as the name.
175175
CompilerType type = desugared_type->GetForwardCompilerType();
176-
if (auto swift_ast_ctx =
176+
if (auto ts =
177177
type.GetTypeSystem().dyn_cast_or_null<TypeSystemSwift>())
178-
preferred_name =
179-
swift_ast_ctx->GetMangledTypeName(type.GetOpaqueQualType());
178+
preferred_name = ts->GetMangledTypeName(type.GetOpaqueQualType());
180179
}
181180
}
182181
}

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserSwift.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ class DWARFASTParserSwift : public lldb_private::plugin::dwarf::DWARFASTParser,
3737

3838
virtual ~DWARFASTParserSwift();
3939

40+
static std::pair<lldb::TypeSP, lldb_private::CompilerType>
41+
ResolveTypeAlias(lldb_private::CompilerType alias);
4042
lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
4143
const DWARFDIE &die,
4244
bool *type_is_new_ptr) override;

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserSwiftDescriptorFinder.cpp

Lines changed: 91 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,87 @@ findUnsubstitutedGenericTypeAndDIE(TypeSystemSwiftTypeRef &ts,
5656
ts.GetTypeFromMangledTypename(ConstString(mangled_name));
5757
return {{unsubstituted_type, unsubstituted_die}};
5858
}
59+
60+
lldb_private::CompilerType static MapTypeIntoContext(
61+
TypeSystemSwiftTypeRef &ts, lldb_private::CompilerType context,
62+
lldb_private::CompilerType type) {
63+
return ts.ApplySubstitutions(
64+
type.GetOpaqueQualType(),
65+
ts.GetSubstitutions(context.GetOpaqueQualType()));
66+
}
67+
68+
std::pair<lldb::TypeSP, lldb_private::CompilerType>
69+
DWARFASTParserSwift::ResolveTypeAlias(lldb_private::CompilerType alias) {
70+
if (!alias)
71+
return {};
72+
auto ts_sp = alias.GetTypeSystem().dyn_cast_or_null<TypeSystemSwiftTypeRef>();
73+
if (!ts_sp)
74+
return {};
75+
auto &ts = *ts_sp;
76+
auto *dwarf = llvm::dyn_cast_or_null<SymbolFileDWARF>(ts.GetSymbolFile());
77+
if (!dwarf)
78+
return {};
79+
80+
// Type aliases are (for LLVM implementation reasons) using the
81+
// DW_AT_name as linkage name, so they can't be looked up by base
82+
// name. This should be fixed.
83+
// Meanwhile, instead find them inside their parent type.
84+
CompilerType parent_ctx = ts.GetParentType(alias.GetOpaqueQualType());
85+
if (!parent_ctx)
86+
return {};
87+
88+
DWARFDIE parent_die;
89+
if (TypeSP parent_type =
90+
ts.FindTypeInModule(parent_ctx.GetOpaqueQualType())) {
91+
parent_die = dwarf->GetDIE(parent_type->GetID());
92+
auto unsubstituted_pair =
93+
findUnsubstitutedGenericTypeAndDIE(ts, parent_die);
94+
if (unsubstituted_pair)
95+
parent_die = unsubstituted_pair->second;
96+
}
97+
if (!parent_die)
98+
return {};
99+
std::string alias_name = ts.GetBaseName(alias.GetOpaqueQualType());
100+
for (DWARFDIE child_die : parent_die.children()) {
101+
auto tag = child_die.Tag();
102+
if (tag == DW_TAG_member)
103+
continue;
104+
std::string base_name;
105+
const auto *name =
106+
child_die.GetAttributeValueAsString(llvm::dwarf::DW_AT_name, "");
107+
if (name && *name == '$') {
108+
CompilerType candidate = ts.GetTypeFromMangledTypename(ConstString(name));
109+
base_name = ts.GetBaseName(candidate.GetOpaqueQualType());
110+
} else {
111+
base_name = name;
112+
}
113+
if (base_name != alias_name)
114+
continue;
115+
116+
// Follow the typedef.
117+
auto *dwarf_parser = ts.GetDWARFParser();
118+
if (!dwarf_parser)
119+
return {};
120+
Type *t = dwarf_parser->GetTypeForDIE(child_die);
121+
if (!t)
122+
return {};
123+
CompilerType cty = t->GetForwardCompilerType();
124+
if (ts.IsMeaninglessWithoutDynamicResolution(cty.GetOpaqueQualType())) {
125+
// Substitute the parameters in the LHS of the BGTAT.
126+
if (ts.IsBoundGenericAliasType(alias.GetOpaqueQualType())) {
127+
auto subs = ts.GetSubstitutions(alias.GetOpaqueQualType());
128+
while (subs.size() > 1)
129+
subs.erase(subs.begin());
130+
cty = ts.ApplySubstitutions(cty.GetOpaqueQualType(), subs);
131+
}
132+
// Substitute the parameters of the RHS of the (BGT)AT.
133+
return {t->shared_from_this(), MapTypeIntoContext(ts, parent_ctx, cty)};
134+
}
135+
return {t->shared_from_this(), cty};
136+
}
137+
return {};
138+
}
139+
59140
/// Given a type system and a typeref, return the compiler type and die of the
60141
/// type that matches that mangled name, looking up the in the type system's
61142
/// module's debug information.
@@ -79,10 +160,17 @@ getTypeAndDie(TypeSystemSwiftTypeRef &ts,
79160
auto *dwarf = llvm::cast_or_null<SymbolFileDWARF>(ts.GetSymbolFile());
80161
if (!dwarf)
81162
return {};
82-
auto lldb_type = ts.FindTypeInModule(type.GetOpaqueQualType());
163+
TypeSP lldb_type = ts.FindTypeInModule(type.GetOpaqueQualType());
164+
if (!lldb_type) {
165+
std::tie(lldb_type, type) = DWARFASTParserSwift::ResolveTypeAlias(type);
166+
if (lldb_type) {
167+
auto die = dwarf->GetDIE(lldb_type->GetID());
168+
return {{type, die}};
169+
}
170+
}
83171
if (!lldb_type) {
84-
// TODO: for embedded Swift this is fine but consult other modules here for
85-
// general case?
172+
// TODO: for embedded Swift this is fine but consult other modules
173+
// here for general case?
86174
LLDB_LOGV(GetLog(LLDBLog::Types), "Could not find type {0} in module",
87175
type.GetMangledTypeName());
88176
return {};
@@ -375,7 +463,6 @@ DWARFASTParserSwift::getFieldDescriptor(const swift::reflection::TypeRef *TR) {
375463
lldb_private::AutoBool::False &&
376464
"Full DWARF debugging for Swift is disabled!");
377465

378-
379466
auto pair = getTypeAndDie(m_swift_typesystem, TR);
380467
if (!pair)
381468
return nullptr;

0 commit comments

Comments
 (0)