Skip to content

Commit e32a206

Browse files
committed
Lazy-initialize Swift runtime in backwards interop synth provider.
Otherwise the Swift runtime and scratch context will be initialized in any process that contains C++ struct types, which costs performance and produces spurious warnings if no Swift runtime is available. rdar://116533409 (cherry picked from commit 3bce4a2)
1 parent 1511e98 commit e32a206

File tree

1 file changed

+61
-48
lines changed

1 file changed

+61
-48
lines changed

lldb/source/Plugins/Language/Swift/SwiftLanguage.cpp

Lines changed: 61 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -735,9 +735,8 @@ SwiftLanguage::GetHardcodedSummaries() {
735735
return g_formatters;
736736
}
737737

738-
static CompilerType
739-
ExtractSwiftTypeFromCxxInteropType(CompilerType type, TypeSystemSwift &ts,
740-
SwiftLanguageRuntime &runtime) {
738+
static llvm::StringRef
739+
ExtractSwiftTypeNameFromCxxInteropType(CompilerType type) {
741740
// Try to recognize a Swift type wrapped in a C++ interop wrapper class.
742741
// These types have a typedef from a char to the swift mangled name, and a
743742
// static constexpr char field whose type is the typedef, and whose name
@@ -767,8 +766,6 @@ ExtractSwiftTypeFromCxxInteropType(CompilerType type, TypeSystemSwift &ts,
767766
}
768767

769768
const clang::RecordDecl *record_decl = record_type->getDecl();
770-
CompilerType swift_type;
771-
772769
for (auto *child_decl : record_decl->decls()) {
773770
auto *var_decl = llvm::dyn_cast<clang::VarDecl>(child_decl);
774771
if (!var_decl)
@@ -787,39 +784,46 @@ ExtractSwiftTypeFromCxxInteropType(CompilerType type, TypeSystemSwift &ts,
787784
if (!decl)
788785
break;
789786

790-
auto swift_name = decl->getName();
791-
if (!swift::Demangle::isMangledName(swift_name))
792-
break;
793-
794-
swift_type = ts.GetTypeFromMangledTypename(ConstString(swift_name));
795-
break;
796-
}
797-
798-
if (swift_type) {
799-
auto bound_type = runtime.BindGenericTypeParameters(
800-
swift_type, [&](unsigned depth, unsigned index) -> CompilerType {
801-
assert(depth == 0 && "Unexpected depth! C++ interop does not support "
802-
"nested generic parameters");
803-
if (depth > 0)
804-
return {};
805-
806-
auto templated_type = type.GetTypeTemplateArgument(index);
807-
auto substituted_type =
808-
ExtractSwiftTypeFromCxxInteropType(templated_type, ts, runtime);
809-
810-
// The generic type might also not be a user defined type which
811-
// ExtractSwiftTypeFromCxxInteropType can find, but which is still
812-
// convertible to Swift (for example, int -> Int32). Attempt to
813-
// convert it to a Swift type.
814-
if (!substituted_type)
815-
substituted_type = ts.ConvertClangTypeToSwiftType(templated_type);
816-
return substituted_type;
817-
});
818-
return bound_type;
787+
return decl->getName();
819788
}
820789
return {};
821790
}
822791

792+
static CompilerType ExtractSwiftTypeFromCxxInteropTypeName(
793+
CompilerType type, llvm::StringRef swift_name, TypeSystemSwift &ts,
794+
SwiftLanguageRuntime &swift_runtime) {
795+
if (!swift::Demangle::isMangledName(swift_name))
796+
return {};
797+
798+
CompilerType swift_type =
799+
ts.GetTypeFromMangledTypename(ConstString(swift_name));
800+
if (!swift_type)
801+
return {};
802+
803+
auto bound_type = swift_runtime.BindGenericTypeParameters(
804+
swift_type, [&](unsigned depth, unsigned index) -> CompilerType {
805+
assert(depth == 0 && "Unexpected depth! C++ interop does not support "
806+
"nested generic parameters");
807+
if (depth > 0)
808+
return {};
809+
810+
CompilerType templated_type = type.GetTypeTemplateArgument(index);
811+
CompilerType substituted_type = ExtractSwiftTypeFromCxxInteropTypeName(
812+
templated_type,
813+
ExtractSwiftTypeNameFromCxxInteropType(templated_type), ts,
814+
swift_runtime);
815+
816+
// The generic type might also not be a user defined type which
817+
// ExtractSwiftTypeFromCxxInteropType can find, but which is still
818+
// convertible to Swift (for example, int -> Int32). Attempt to
819+
// convert it to a Swift type.
820+
if (!substituted_type)
821+
substituted_type = ts.ConvertClangTypeToSwiftType(templated_type);
822+
return substituted_type;
823+
});
824+
return bound_type;
825+
}
826+
823827
/// Synthetic child that wraps a value object.
824828
class ValueObjectWrapperSyntheticChildren : public SyntheticChildren {
825829
class ValueObjectWrapperFrontEndProvider : public SyntheticChildrenFrontEnd {
@@ -1002,30 +1006,39 @@ SwiftLanguage::GetHardcodedSynthetics() {
10021006
FormatManager &format_manager)
10031007
-> lldb::SyntheticChildrenSP {
10041008
Log *log(GetLog(LLDBLog::DataFormatters));
1009+
auto type = valobj.GetCompilerType();
10051010

1011+
// First, check whether this is a C++ wrapped Swift type.
1012+
llvm::StringRef swift_type_name =
1013+
ExtractSwiftTypeNameFromCxxInteropType(type);
1014+
if (swift_type_name.empty()) {
1015+
LLDB_LOGV(log, "[Matching CxxBridgedSyntheticChildProvider] - "
1016+
"Did not find Swift type.");
1017+
return nullptr;
1018+
}
1019+
1020+
// Extract the Swift type.
10061021
ProcessSP process_sp(valobj.GetProcessSP());
10071022
auto *swift_runtime = SwiftLanguageRuntime::Get(process_sp);
1008-
if (!swift_runtime) {
1023+
if (!swift_runtime)
10091024
LLDB_LOGV(log, "[Matching CxxBridgedSyntheticChildProvider] - "
10101025
"Could not get the swift runtime.");
1011-
return nullptr;
1012-
}
10131026

1014-
auto scratch_ctx = valobj.GetSwiftScratchContext();
1015-
if (!scratch_ctx) {
1027+
llvm::Optional<SwiftScratchContextReader> scratch_ctx_reader =
1028+
valobj.GetSwiftScratchContext();
1029+
if (!scratch_ctx_reader || !scratch_ctx_reader->get()) {
10161030
LLDB_LOGV(log, "[Matching CxxBridgedSyntheticChildProvider] - "
1017-
"Could not get the swift scratch context.");
1031+
"Could not get the Swift scratch context.");
10181032
return nullptr;
10191033
}
1020-
auto &type_system_swift = **scratch_ctx;
1021-
1022-
auto type = valobj.GetCompilerType();
1023-
1024-
auto swift_type = ExtractSwiftTypeFromCxxInteropType(
1025-
type, type_system_swift, *swift_runtime);
1034+
auto &ts = *scratch_ctx_reader->get();
1035+
CompilerType swift_type = ExtractSwiftTypeFromCxxInteropTypeName(
1036+
type, swift_type_name, ts, *swift_runtime);
10261037
if (!swift_type) {
1027-
LLDB_LOGV(log, "[Matching CxxBridgedSyntheticChildProvider] - "
1028-
"Did not find Swift type.");
1038+
LLDB_LOGV(log,
1039+
"[Matching CxxBridgedSyntheticChildProvider] - "
1040+
"Did not find Swift type for type name \"{0}\".",
1041+
swift_type_name);
10291042
return nullptr;
10301043
}
10311044

0 commit comments

Comments
 (0)