Skip to content

Commit 3bce4a2

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
1 parent 299c632 commit 3bce4a2

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
@@ -738,9 +738,8 @@ SwiftLanguage::GetHardcodedSummaries() {
738738
return g_formatters;
739739
}
740740

741-
static CompilerType
742-
ExtractSwiftTypeFromCxxInteropType(CompilerType type, TypeSystemSwift &ts,
743-
SwiftLanguageRuntime &runtime) {
741+
static llvm::StringRef
742+
ExtractSwiftTypeNameFromCxxInteropType(CompilerType type) {
744743
// Try to recognize a Swift type wrapped in a C++ interop wrapper class.
745744
// These types have a typedef from a char to the swift mangled name, and a
746745
// static constexpr char field whose type is the typedef, and whose name
@@ -770,8 +769,6 @@ ExtractSwiftTypeFromCxxInteropType(CompilerType type, TypeSystemSwift &ts,
770769
}
771770

772771
const clang::RecordDecl *record_decl = record_type->getDecl();
773-
CompilerType swift_type;
774-
775772
for (auto *child_decl : record_decl->decls()) {
776773
auto *var_decl = llvm::dyn_cast<clang::VarDecl>(child_decl);
777774
if (!var_decl)
@@ -790,39 +787,46 @@ ExtractSwiftTypeFromCxxInteropType(CompilerType type, TypeSystemSwift &ts,
790787
if (!decl)
791788
break;
792789

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

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

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

1017-
auto scratch_ctx = valobj.GetSwiftScratchContext();
1018-
if (!scratch_ctx) {
1030+
llvm::Optional<SwiftScratchContextReader> scratch_ctx_reader =
1031+
valobj.GetSwiftScratchContext();
1032+
if (!scratch_ctx_reader || !scratch_ctx_reader->get()) {
10191033
LLDB_LOGV(log, "[Matching CxxBridgedSyntheticChildProvider] - "
1020-
"Could not get the swift scratch context.");
1034+
"Could not get the Swift scratch context.");
10211035
return nullptr;
10221036
}
1023-
auto &type_system_swift = **scratch_ctx;
1024-
1025-
auto type = valobj.GetCompilerType();
1026-
1027-
auto swift_type = ExtractSwiftTypeFromCxxInteropType(
1028-
type, type_system_swift, *swift_runtime);
1037+
auto &ts = *scratch_ctx_reader->get();
1038+
CompilerType swift_type = ExtractSwiftTypeFromCxxInteropTypeName(
1039+
type, swift_type_name, ts, *swift_runtime);
10291040
if (!swift_type) {
1030-
LLDB_LOGV(log, "[Matching CxxBridgedSyntheticChildProvider] - "
1031-
"Did not find Swift type.");
1041+
LLDB_LOGV(log,
1042+
"[Matching CxxBridgedSyntheticChildProvider] - "
1043+
"Did not find Swift type for type name \"{0}\".",
1044+
swift_type_name);
10321045
return nullptr;
10331046
}
10341047

0 commit comments

Comments
 (0)