Skip to content

Commit 233d29a

Browse files
authored
Merge pull request swiftlang#16616 from DougGregor/emit-public-type-metadata-accessors
Add -emit-public-type-metadata-accessors to work around metadata linkage bug.
2 parents 9278369 + 20832fd commit 233d29a

File tree

7 files changed

+48
-0
lines changed

7 files changed

+48
-0
lines changed

include/swift/Basic/LangOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,9 @@ namespace swift {
223223
/// Enables key path resilience.
224224
bool EnableKeyPathResilience = false;
225225

226+
/// Enables public emission of private metadata accessors.
227+
bool EmitPublicTypeMetadataAccessors = false;
228+
226229
/// If set to true, the diagnosis engine can assume the emitted diagnostics
227230
/// will be used in editor. This usually leads to more aggressive fixit.
228231
bool DiagnosticsEditorMode = false;

include/swift/Option/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,11 @@ def warn_swift3_objc_inference : Flag<["-"], "warn-swift3-objc-inference">,
355355
Alias<warn_swift3_objc_inference_complete>,
356356
Flags<[FrontendOption, DoesNotAffectIncrementalBuild, HelpHidden]>;
357357

358+
def emit_public_type_metadata_accessors :
359+
Flag<["-"], "emit-public-type-metadata-accessors">,
360+
Flags<[FrontendOption]>,
361+
HelpText<"Emit all type metadata accessors as public">;
362+
358363
def Rpass_EQ : Joined<["-"], "Rpass=">,
359364
Flags<[FrontendOption]>,
360365
HelpText<"Report performed transformations by optimization passes whose "

lib/Driver/ToolChains.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,8 @@ static void addCommonFrontendArgs(const ToolChain &TC, const OutputInfo &OI,
183183
options::OPT_warn_swift3_objc_inference_minimal,
184184
options::OPT_warn_swift3_objc_inference_complete);
185185
inputArgs.AddLastArg(arguments, options::OPT_typo_correction_limit);
186+
inputArgs.AddLastArg(arguments,
187+
options::OPT_emit_public_type_metadata_accessors);
186188
inputArgs.AddLastArg(arguments, options::OPT_enable_app_extension);
187189
inputArgs.AddLastArg(arguments, options::OPT_enable_testing);
188190
inputArgs.AddLastArg(arguments, options::OPT_g_Group);

lib/Frontend/CompilerInvocation.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,9 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
309309
}
310310
}
311311

312+
Opts.EmitPublicTypeMetadataAccessors =
313+
Args.hasArg(OPT_emit_public_type_metadata_accessors);
314+
312315
Opts.EnableNSKeyedArchiverDiagnostics =
313316
Args.hasFlag(OPT_enable_nskeyedarchiver_diagnostics,
314317
OPT_disable_nskeyedarchiver_diagnostics,

lib/IRGen/MetadataRequest.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,17 @@ bool irgen::isTypeMetadataAccessTrivial(IRGenModule &IGM, CanType type) {
589589
return false;
590590
}
591591

592+
/// Determine whether we should promote the type metadata access function
593+
/// for the given nominal type to "public".
594+
static bool promoteMetadataAccessFunctionToPublic(
595+
const NominalTypeDecl *nominal) {
596+
ASTContext &ctx = nominal->getASTContext();
597+
598+
// When -emit-public-type-metadata-accessors is provided, promote all
599+
// of the metadata access functions to public.
600+
return ctx.LangOpts.EmitPublicTypeMetadataAccessors;
601+
}
602+
592603
/// Return the standard access strategy for getting a non-dependent
593604
/// type metadata object.
594605
MetadataAccessStrategy irgen::getTypeMetadataAccessStrategy(CanType type) {
@@ -621,8 +632,12 @@ MetadataAccessStrategy irgen::getTypeMetadataAccessStrategy(CanType type) {
621632
case FormalLinkage::PublicUnique:
622633
return MetadataAccessStrategy::PublicUniqueAccessor;
623634
case FormalLinkage::HiddenUnique:
635+
if (promoteMetadataAccessFunctionToPublic(nominal))
636+
return MetadataAccessStrategy::PublicUniqueAccessor;
624637
return MetadataAccessStrategy::HiddenUniqueAccessor;
625638
case FormalLinkage::Private:
639+
if (promoteMetadataAccessFunctionToPublic(nominal))
640+
return MetadataAccessStrategy::PublicUniqueAccessor;
626641
return MetadataAccessStrategy::PrivateAccessor;
627642

628643
case FormalLinkage::PublicNonUnique:
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
func foo() -> Any {
2+
return Wrapper()
3+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %swift -module-name test -target x86_64-apple-macosx10.9 -emit-ir -parse-stdlib -emit-public-type-metadata-accessors -primary-file %s %S/Inputs/emit_public_type_metadata_accessors_other.swift | %FileCheck --check-prefix=CHECK-PUBLIC %s
2+
3+
// RUN: %swift -module-name test -target x86_64-apple-macosx10.9 -emit-ir -parse-stdlib -primary-file %s %S/Inputs/emit_public_type_metadata_accessors_other.swift | %FileCheck --check-prefix=CHECK-NONPUBLIC %s
4+
5+
private class C { }
6+
7+
// CHECK-PUBLIC: define swiftcc %swift.metadata_response @"$S4test3Foo33_DEC9477CC6E8E6E7A9CE422B1DBE7EA4LLVMa"
8+
// CHECK-NONPUBLIC: define internal swiftcc %swift.metadata_response @"$S4test3Foo33_DEC9477CC6E8E6E7A9CE422B1DBE7EA4LLVMa"
9+
private struct Foo {
10+
private let c: C = C()
11+
}
12+
13+
public struct Wrapper {
14+
private let foo: Foo = Foo()
15+
}
16+
17+

0 commit comments

Comments
 (0)