Skip to content

Commit fd9ae4c

Browse files
authored
Merge pull request #72023 from beccadax/lazy-objc-workaround
Add workaround flag for lazy import-as-member
2 parents 1752b48 + 54fd4b0 commit fd9ae4c

File tree

14 files changed

+76
-8
lines changed

14 files changed

+76
-8
lines changed

include/swift/AST/ClangModuleLoader.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ class ClangModuleLoader : public ModuleLoader {
144144
virtual clang::Sema &getClangSema() const = 0;
145145
virtual const clang::CompilerInstance &getClangInstance() const = 0;
146146
virtual void printStatistics() const = 0;
147+
virtual void dumpSwiftLookupTables() const = 0;
147148

148149
/// Returns the module that contains imports and declarations from all loaded
149150
/// Objective-C header files.

include/swift/Basic/LangOptions.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,11 @@ namespace swift {
380380
/// Enable experimental eager Clang module diagnostics.
381381
bool EnableExperimentalEagerClangModuleDiagnostics = false;
382382

383+
/// Force ClangImporter's import-as-member extensions to load thier members
384+
/// immediately, bypassing their SwiftLookupTables. This emulates an
385+
/// implementation quirk of previous compilers.
386+
bool DisableNamedLazyImportAsMemberLoading = false;
387+
383388
/// Enable inference of Sendable conformances for public types.
384389
bool EnableInferPublicSendable = false;
385390

include/swift/ClangImporter/ClangImporter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ class ClangImporter final : public ClangModuleLoader {
538538
void printStatistics() const override;
539539

540540
/// Dump Swift lookup tables.
541-
void dumpSwiftLookupTables();
541+
void dumpSwiftLookupTables() const override;
542542

543543
/// Given the path of a Clang module, collect the names of all its submodules.
544544
/// Calling this function does not load the module.

include/swift/Frontend/FrontendOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,10 @@ class FrontendOptions {
280280
/// termination.
281281
bool PrintClangStats = false;
282282

283+
/// Indicates whether or not the Clang importer should dump lookup tables
284+
/// upon termination.
285+
bool DumpClangLookupTables = false;
286+
283287
/// Indicates whether standard help should be shown.
284288
bool PrintHelp = false;
285289

include/swift/Option/FrontendOptions.td

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,13 @@ def debug_constraints_on_line_EQ : Joined<["-"], "debug-constraints-on-line=">,
372372
Alias<debug_constraints_on_line>;
373373

374374
def disable_named_lazy_member_loading : Flag<["-"], "disable-named-lazy-member-loading">,
375-
HelpText<"Disable per-name lazy member loading">;
375+
HelpText<"Disable per-name lazy member loading (obsolete)">;
376+
377+
def disable_named_lazy_import_as_member_loading :
378+
Flag<["-"], "disable-named-lazy-import-as-member-loading">,
379+
HelpText<"Import all of a type's import-as-member globals together, as Swift "
380+
"5.10 and earlier did; temporary workaround for modules that are "
381+
"sensitive to this change">;
376382

377383
def dump_requirement_machine : Flag<["-"], "dump-requirement-machine">,
378384
HelpText<"Enables dumping rewrite systems from the generics implementation">;
@@ -580,6 +586,10 @@ def stack_promotion_limit : Separate<["-"], "stack-promotion-limit">,
580586
def dump_clang_diagnostics : Flag<["-"], "dump-clang-diagnostics">,
581587
HelpText<"Dump Clang diagnostics to stderr">;
582588

589+
def dump_clang_lookup_tables : Flag<["-"], "dump-clang-lookup-tables">,
590+
HelpText<"Dump the importer's Swift-name-to-Clang-name lookup tables to "
591+
"stderr">;
592+
583593
def disable_modules_validate_system_headers : Flag<["-"], "disable-modules-validate-system-headers">,
584594
HelpText<"Disable validating system headers in the Clang importer">;
585595

lib/AST/NameLookup.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1487,10 +1487,25 @@ void MemberLookupTable::addMembers(DeclRange members) {
14871487
}
14881488
}
14891489

1490+
static bool shouldLoadMembersImmediately(ExtensionDecl *ext) {
1491+
assert(ext->hasLazyMembers());
1492+
if (ext->wasDeserialized() || ext->hasClangNode())
1493+
return false;
1494+
1495+
// This extension is lazy but is not deserialized or backed by a clang node,
1496+
// so it's a ClangImporter extension containing import-as-member globals.
1497+
// Historically, Swift forced these extensions to load their members
1498+
// immediately, bypassing the module's SwiftLookupTable. Using the
1499+
// SwiftLookupTable *ought* to work the same, but in practice it sometimes
1500+
// gives different results when a header is not properly modularized. Provide
1501+
// a flag to temporarily re-enable the old behavior.
1502+
return ext->getASTContext().LangOpts.DisableNamedLazyImportAsMemberLoading;
1503+
}
1504+
14901505
void MemberLookupTable::addExtension(ExtensionDecl *ext) {
14911506
// If we can lazy-load this extension, only take the members we've loaded
14921507
// so far.
1493-
if (ext->hasLazyMembers()) {
1508+
if (ext->hasLazyMembers() && !shouldLoadMembersImmediately(ext)) {
14941509
addMembers(ext->getCurrentMembersWithoutLoading());
14951510
clearLazilyCompleteCache();
14961511
clearLazilyCompleteForMacroExpansionCache();

lib/ClangImporter/ClangImporter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6269,7 +6269,7 @@ EffectiveClangContext ClangImporter::Implementation::getEffectiveClangContext(
62696269
return EffectiveClangContext();
62706270
}
62716271

6272-
void ClangImporter::dumpSwiftLookupTables() {
6272+
void ClangImporter::dumpSwiftLookupTables() const {
62736273
Impl.dumpSwiftLookupTables();
62746274
}
62756275

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ bool ArgsToFrontendOptionsConverter::convert(
170170
computeDebugTimeOptions();
171171
computeTBDOptions();
172172

173+
Opts.DumpClangLookupTables |= Args.hasArg(OPT_dump_clang_lookup_tables);
174+
173175
Opts.CheckOnoneSupportCompleteness = Args.hasArg(OPT_check_onone_completeness);
174176

175177
Opts.ParseStdlib |= Args.hasArg(OPT_parse_stdlib);

lib/Frontend/CompilerInvocation.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,9 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
626626
!Args.hasArg(OPT_disable_experimental_clang_importer_diagnostics) &&
627627
Args.hasArg(OPT_enable_experimental_eager_clang_module_diagnostics);
628628

629+
Opts.DisableNamedLazyImportAsMemberLoading |=
630+
Args.hasArg(OPT_disable_named_lazy_import_as_member_loading);
631+
629632
Opts.DisableImplicitConcurrencyModuleImport |=
630633
Args.hasArg(OPT_disable_implicit_concurrency_module_import);
631634

lib/FrontendTool/FrontendTool.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,9 @@ static void performEndOfPipelineActions(CompilerInstance &Instance) {
11171117
if (auto *stats = ctx.Stats)
11181118
countASTStats(*stats, Instance);
11191119

1120+
if (opts.DumpClangLookupTables && ctx.getClangModuleLoader())
1121+
ctx.getClangModuleLoader()->dumpSwiftLookupTables();
1122+
11201123
// Report mangling stats if there was no error.
11211124
if (!ctx.hadError())
11221125
Mangle::printManglingStats();

test/IDE/dump_swift_lookup_tables.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
// RUN: %target-swift-ide-test -dump-importer-lookup-table -source-filename %s -import-objc-header %S/Inputs/swift_name.h -I %S/Inputs/custom-modules > %t.log 2>&1
2-
// RUN: %FileCheck %s < %t.log
1+
// RUN: %target-swift-ide-test -dump-importer-lookup-table -source-filename %s -import-objc-header %S/Inputs/swift_name.h -I %S/Inputs/custom-modules > %t.ide-test.log 2>&1
2+
// RUN: %FileCheck %s < %t.ide-test.log
3+
4+
// RUN: %target-typecheck-verify-swift -dump-clang-lookup-tables -import-objc-header %S/Inputs/swift_name.h -I %S/Inputs/custom-modules > %t.frontend.log 2>&1
5+
// RUN: %FileCheck %s < %t.frontend.log
36

47
// REQUIRES: objc_interop
58
import ImportAsMember

test/IDE/dump_swift_lookup_tables_objc.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
// RUN: %target-swift-ide-test -dump-importer-lookup-table -source-filename %s -import-objc-header %S/Inputs/swift_name_objc.h > %t.log 2>&1
2-
// RUN: %FileCheck %s < %t.log
1+
// RUN: %target-swift-ide-test -dump-importer-lookup-table -source-filename %s -import-objc-header %S/Inputs/swift_name_objc.h > %t.ide-test.log 2>&1
2+
// RUN: %FileCheck %s < %t.ide-test.log
3+
4+
// RUN: %target-typecheck-verify-swift -dump-clang-lookup-tables -import-objc-header %S/Inputs/swift_name_objc.h > %t.frontend.log 2>&1
5+
// RUN: %FileCheck %s < %t.frontend.log
36

47
// REQUIRES: objc_interop
58
// REQUIRES: OS=macosx

test/NameLookup/Inputs/NamedLazyMembers/NamedLazyMembers.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,6 @@
138138

139139
@interface PrivateDoer(Category) <PrivateMethods>
140140
@end
141+
142+
typedef NSString * const SimpleDoerMode NS_TYPED_ENUM NS_SWIFT_NAME(SimpleDoer.Mode);
143+
typedef NSString * const SimpleDoerKind NS_TYPED_ENUM NS_SWIFT_NAME(SimpleDoer.Kind);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// REQUIRES: objc_interop
2+
// REQUIRES: OS=macosx
3+
4+
// RUN: %empty-directory(%t/stats-lazy)
5+
// RUN: %empty-directory(%t/stats-eager)
6+
7+
// RUN: %target-swift-frontend -typecheck -I %S/Inputs/NamedLazyMembers %s -stats-output-dir %t/stats-lazy
8+
// RUN: %target-swift-frontend -typecheck -I %S/Inputs/NamedLazyMembers %s -stats-output-dir %t/stats-eager -disable-named-lazy-import-as-member-loading
9+
10+
// stats-lazy should only have imported SimpleDoer.Mode; stats-eager should also
11+
// have imported SimpleDoer.Kind
12+
// RUN: %{python} %utils/process-stats-dir.py --evaluate-delta 'NumTotalClangImportedEntities == 1' %t/stats-lazy %t/stats-eager
13+
14+
import NamedLazyMembers
15+
16+
func fn(_: SimpleDoer.Mode) {}

0 commit comments

Comments
 (0)