Skip to content

Commit 2504bee

Browse files
authored
Merge pull request #85043 from beccadax/mod-squad-interface
[SE-0491] Conditionally emit module selectors into swiftinterfaces
2 parents 591fec2 + 9454c0a commit 2504bee

File tree

12 files changed

+265
-19
lines changed

12 files changed

+265
-19
lines changed

include/swift/AST/PrintOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,9 @@ struct PrintOptions {
580580
/// with types sharing a name with a module.
581581
bool AliasModuleNames = false;
582582

583+
/// Use module selectors when printing names.
584+
bool UseModuleSelectors = false;
585+
583586
/// Name of the modules that have been aliased in AliasModuleNames mode.
584587
/// Ideally we would use something other than a string to identify a module,
585588
/// but since one alias can apply to more than one module, strings happen
@@ -769,6 +772,7 @@ struct PrintOptions {
769772
///
770773
/// \see swift::emitSwiftInterface
771774
static PrintOptions printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
775+
bool useModuleSelectors,
772776
bool preferTypeRepr,
773777
bool printFullConvention,
774778
InterfaceMode interfaceMode,

include/swift/Basic/BlockListAction.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,6 @@ BLOCKLIST_ACTION(ShouldDisableOwnershipVerification)
2727
BLOCKLIST_ACTION(SkipEmittingFineModuleTrace)
2828
BLOCKLIST_ACTION(SkipIndexingModule)
2929
BLOCKLIST_ACTION(ShouldUseTypeCheckerPerfHacks)
30+
BLOCKLIST_ACTION(DisableModuleSelectorsInModuleInterface)
3031

3132
#undef BLOCKLIST_ACTION

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,8 @@ struct InterfaceSubContextDelegateImpl : InterfaceSubContextDelegate {
646646
const LangOptions &LangOpts,
647647
const ClangImporterOptions &clangImporterOpts,
648648
const CASOptions &casOpts,
649-
bool suppressNotes, bool suppressRemarks);
649+
bool suppressNotes, bool suppressRemarks,
650+
PrintDiagnosticNamesMode diagnosticNamesMode);
650651
bool extractSwiftInterfaceVersionAndArgs(CompilerInvocation &subInvocation,
651652
DiagnosticEngine &subInstanceDiags,
652653
SwiftInterfaceInfo &interfaceInfo,

include/swift/Frontend/ModuleInterfaceSupport.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ struct ModuleInterfaceOptions {
4040
/// with types sharing a name with a module.
4141
bool AliasModuleNames = false;
4242

43+
/// Should we emit module selectors into the module interface?
44+
bool UseModuleSelectors = false;
45+
4346
/// See \ref FrontendOptions.PrintFullConvention.
4447
/// [TODO: Clang-type-plumbing] This check should go away.
4548
bool PrintFullConvention = false;

include/swift/Option/Options.td

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,16 @@ def emit_variant_package_module_interface_path :
752752
MetaVarName<"<path>">,
753753
HelpText<"Output package module interface file for the target variant to <path>">;
754754

755+
def enable_module_selectors_in_module_interface :
756+
Flag<["-"], "enable-module-selectors-in-module-interface">,
757+
Flags<[FrontendOption, NoInteractiveOption]>,
758+
HelpText<"When emitting module interface files, use module selectors to avoid name collisions">;
759+
760+
def disable_module_selectors_in_module_interface :
761+
Flag<["-"], "disable-module-selectors-in-module-interface">,
762+
Flags<[FrontendOption, NoInteractiveOption]>,
763+
HelpText<"When emitting module interface files, do not use module selectors to avoid name collisions">;
764+
755765
def verify_emitted_module_interface :
756766
Flag<["-"], "verify-emitted-module-interface">,
757767
Flags<[NoInteractiveOption, DoesNotAffectIncrementalBuild]>,

lib/AST/ASTPrinter.cpp

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ struct PrintWithOpaqueResultTypeKeywordRAII {
263263
};
264264

265265
PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
266+
bool useModuleSelectors,
266267
bool preferTypeRepr,
267268
bool printFullConvention,
268269
InterfaceMode interfaceMode,
@@ -276,6 +277,7 @@ PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
276277
result.PrintLongAttrsOnSeparateLines = true;
277278
result.TypeDefinitions = true;
278279
result.CurrentModule = ModuleToPrint;
280+
result.UseModuleSelectors = useModuleSelectors;
279281
result.FullyQualifiedTypes = true;
280282
result.FullyQualifiedTypesIfAmbiguous = true;
281283
result.FullyQualifiedExtendedTypesIfAmbiguous = true;
@@ -6058,9 +6060,8 @@ class TypePrinter : public TypeVisitor<TypePrinter, void, NonRecursivePrintOptio
60586060
return Options.CurrentModule->getVisibleClangModules(Options.InterfaceContentKind);
60596061
}
60606062

6061-
template <typename T>
6062-
void printModuleContext(T *Ty) {
6063-
FileUnit *File = cast<FileUnit>(Ty->getDecl()->getModuleScopeContext());
6063+
void printModuleContext(GenericTypeDecl *TyDecl) {
6064+
FileUnit *File = cast<FileUnit>(TyDecl->getModuleScopeContext());
60646065
ModuleDecl *Mod = File->getParentModule();
60656066
StringRef ExportedModuleName = File->getExportedModuleName();
60666067

@@ -6069,7 +6070,7 @@ class TypePrinter : public TypeVisitor<TypePrinter, void, NonRecursivePrintOptio
60696070
// all of these modules may be visible. We therefore need to make sure we
60706071
// choose a module that is visible from the current module. This is possible
60716072
// only if we know what the current module is.
6072-
const clang::Decl *ClangDecl = Ty->getDecl()->getClangDecl();
6073+
const clang::Decl *ClangDecl = TyDecl->getClangDecl();
60736074
if (ClangDecl && Options.CurrentModule) {
60746075
for (auto *Redecl : ClangDecl->redecls()) {
60756076
auto *owningModule = Redecl->getOwningModule();
@@ -6106,12 +6107,10 @@ class TypePrinter : public TypeVisitor<TypePrinter, void, NonRecursivePrintOptio
61066107
}
61076108

61086109
if (Options.UseOriginallyDefinedInModuleNames) {
6109-
Decl *D = Ty->getDecl();
6110-
for (auto attr: D->getAttrs().getAttributes<OriginallyDefinedInAttr>()) {
6110+
if (auto attr =
6111+
TyDecl->getAttrs().getAttribute<OriginallyDefinedInAttr>()) {
61116112
Name = Mod->getASTContext().getIdentifier(
6112-
const_cast<OriginallyDefinedInAttr *>(attr)
6113-
->getManglingModuleName());
6114-
break;
6113+
attr->getManglingModuleName());
61156114
}
61166115
}
61176116

@@ -6122,7 +6121,6 @@ class TypePrinter : public TypeVisitor<TypePrinter, void, NonRecursivePrintOptio
61226121
}
61236122

61246123
Printer.printModuleRef(Mod, Name);
6125-
Printer << ".";
61266124
}
61276125

61286126
template <typename T>
@@ -6140,7 +6138,42 @@ class TypePrinter : public TypeVisitor<TypePrinter, void, NonRecursivePrintOptio
61406138
return M->getRealName().str().starts_with(LLDB_EXPRESSIONS_MODULE_NAME_PREFIX);
61416139
}
61426140

6141+
bool isMemberOfGenericParameter(TypeBase *T) {
6142+
Type parent = nullptr;
6143+
if (auto alias = dyn_cast<TypeAliasType>(T))
6144+
parent = alias->getParent();
6145+
else if (auto generic = T->getAs<AnyGenericType>())
6146+
parent = generic->getParent();
6147+
return parent && parent->isTypeParameter();
6148+
}
6149+
6150+
bool shouldPrintModuleSelector(TypeBase *T) {
6151+
if (!Options.UseModuleSelectors)
6152+
return false;
6153+
6154+
GenericTypeDecl *GTD = T->getAnyGeneric();
6155+
if (!GTD && isa<TypeAliasType>(T))
6156+
GTD = cast<TypeAliasType>(T)->getDecl();
6157+
if (!GTD)
6158+
return false;
6159+
6160+
// Builtin types must always be qualified somehow.
6161+
ModuleDecl *M = GTD->getDeclContext()->getParentModule();
6162+
if (M->isBuiltinModule())
6163+
return true;
6164+
6165+
// A member of a generic parameter can't be qualified by a module selector.
6166+
if (isMemberOfGenericParameter(T))
6167+
return false;
6168+
6169+
// Module selectors skip over local types, so don't add one.
6170+
return GTD->getLocalContext() == nullptr;
6171+
}
6172+
61436173
bool shouldPrintFullyQualified(TypeBase *T) {
6174+
if (Options.UseModuleSelectors)
6175+
return false;
6176+
61446177
if (Options.FullyQualifiedTypes)
61456178
return true;
61466179

@@ -6197,7 +6230,15 @@ class TypePrinter : public TypeVisitor<TypePrinter, void, NonRecursivePrintOptio
61976230
printParentType(parent);
61986231
NameContext = PrintNameContext::TypeMember;
61996232
} else if (shouldPrintFullyQualified(Ty)) {
6200-
printModuleContext(Ty);
6233+
printModuleContext(Ty->getDecl());
6234+
Printer << ".";
6235+
NameContext = PrintNameContext::TypeMember;
6236+
}
6237+
6238+
// We print module selectors whether or not we printed a parent type.
6239+
if (shouldPrintModuleSelector(Ty)) {
6240+
printModuleContext(Ty->getDecl());
6241+
Printer << "::";
62016242
NameContext = PrintNameContext::TypeMember;
62026243
}
62036244

lib/Driver/ToolChains.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,8 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI,
316316
inputArgs.AddLastArg(arguments, options::OPT_module_cache_path);
317317
inputArgs.AddLastArg(arguments, options::OPT_module_link_name);
318318
inputArgs.AddLastArg(arguments, options::OPT_module_abi_name);
319+
inputArgs.AddLastArg(arguments, options::OPT_enable_module_selectors_in_module_interface,
320+
options::OPT_disable_module_selectors_in_module_interface);
319321
inputArgs.AddLastArg(arguments, options::OPT_package_name);
320322
inputArgs.AddLastArg(arguments, options::OPT_export_as);
321323
inputArgs.AddLastArg(arguments, options::OPT_nostdimport);

lib/Frontend/CompilerInvocation.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,8 @@ static void PrintArg(raw_ostream &OS, const char *Arg, StringRef TempDir) {
536536
}
537537

538538
static void ParseModuleInterfaceArgs(ModuleInterfaceOptions &Opts,
539-
ArgList &Args) {
539+
ArgList &Args,
540+
DiagnosticEngine &diags) {
540541
using namespace options;
541542

542543
Opts.PreserveTypesAsWritten |=
@@ -545,6 +546,7 @@ static void ParseModuleInterfaceArgs(ModuleInterfaceOptions &Opts,
545546
Args.hasFlag(OPT_alias_module_names_in_module_interface,
546547
OPT_disable_alias_module_names_in_module_interface,
547548
::getenv("SWIFT_ALIAS_MODULE_NAMES_IN_INTERFACES"));
549+
548550
Opts.PrintFullConvention |=
549551
Args.hasArg(OPT_experimental_print_full_convention);
550552
Opts.DebugPrintInvalidSyntax |=
@@ -558,6 +560,21 @@ static void ParseModuleInterfaceArgs(ModuleInterfaceOptions &Opts,
558560
Opts.setInterfaceMode(PrintOptions::InterfaceMode::Private);
559561
}
560562
}
563+
564+
if (Args.hasArgNoClaim(OPT_enable_module_selectors_in_module_interface)
565+
|| Args.hasArgNoClaim(OPT_disable_module_selectors_in_module_interface)) {
566+
Opts.UseModuleSelectors =
567+
Args.hasFlag(OPT_enable_module_selectors_in_module_interface,
568+
OPT_disable_module_selectors_in_module_interface,
569+
false);
570+
} else if (auto envValue = ::getenv("SWIFT_MODULE_SELECTORS_IN_INTERFACES")) {
571+
Opts.UseModuleSelectors = llvm::StringSwitch<bool>(envValue)
572+
.CasesLower("false", "no", "off", "0", false)
573+
.Default(true);
574+
} else {
575+
// Any heuristics we might add would go here.
576+
Opts.UseModuleSelectors = false;
577+
}
561578
}
562579

563580
/// Checks if an arg is generally allowed to be included
@@ -4174,7 +4191,7 @@ bool CompilerInvocation::parseArgs(
41744191
setMainExecutablePath(mainExecutablePath);
41754192
}
41764193

4177-
ParseModuleInterfaceArgs(ModuleInterfaceOpts, ParsedArgs);
4194+
ParseModuleInterfaceArgs(ModuleInterfaceOpts, ParsedArgs, Diags);
41784195
SaveModuleInterfaceArgs(ModuleInterfaceOpts, FrontendOpts, ParsedArgs, Diags);
41794196

41804197
if (ParseCASArgs(CASOpts, ParsedArgs, Diags, FrontendOpts)) {

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1642,7 +1642,8 @@ void InterfaceSubContextDelegateImpl::inheritOptionsForBuildingInterface(
16421642
FrontendOptions::ActionType requestedAction,
16431643
const SearchPathOptions &SearchPathOpts, const LangOptions &LangOpts,
16441644
const ClangImporterOptions &clangImporterOpts, const CASOptions &casOpts,
1645-
bool suppressNotes, bool suppressRemarks) {
1645+
bool suppressNotes, bool suppressRemarks,
1646+
PrintDiagnosticNamesMode printDiagnosticNames) {
16461647
GenericArgs.push_back("-frontend");
16471648
// Start with a genericSubInvocation that copies various state from our
16481649
// invoking ASTContext.
@@ -1743,6 +1744,20 @@ void InterfaceSubContextDelegateImpl::inheritOptionsForBuildingInterface(
17431744
GenericArgs.push_back("-suppress-remarks");
17441745
}
17451746

1747+
// Inherit the parent invocation's setting for printing diagnostic IDs.
1748+
genericSubInvocation.getDiagnosticOptions().PrintDiagnosticNames =
1749+
printDiagnosticNames;
1750+
switch (printDiagnosticNames) {
1751+
case PrintDiagnosticNamesMode::None:
1752+
break;
1753+
case PrintDiagnosticNamesMode::Identifier:
1754+
GenericArgs.push_back("-debug-diagnostic-names");
1755+
break;
1756+
case PrintDiagnosticNamesMode::Group:
1757+
// FIXME: Currently no flag for Group mode
1758+
break;
1759+
}
1760+
17461761
// Inherit this setting down so that it can affect error diagnostics (mostly
17471762
// by making them non-fatal).
17481763
genericSubInvocation.getLangOptions().DebuggerSupport = LangOpts.DebuggerSupport;
@@ -1849,7 +1864,8 @@ InterfaceSubContextDelegateImpl::InterfaceSubContextDelegateImpl(
18491864
inheritOptionsForBuildingInterface(LoaderOpts.requestedAction, searchPathOpts,
18501865
langOpts, clangImporterOpts, casOpts,
18511866
Diags->getSuppressNotes(),
1852-
Diags->getSuppressRemarks());
1867+
Diags->getSuppressRemarks(),
1868+
Diags->getPrintDiagnosticNamesMode());
18531869
// Configure front-end input.
18541870
auto &SubFEOpts = genericSubInvocation.getFrontendOptions();
18551871
SubFEOpts.RequestedAction = LoaderOpts.requestedAction;

lib/Frontend/ModuleInterfaceSupport.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -884,13 +884,22 @@ bool swift::emitSwiftInterface(raw_ostream &out,
884884

885885
printImports(out, Opts, M, aliasModuleNamesTargets);
886886

887-
bool useExportedModuleNames = Opts.printPublicInterface();
887+
// Apply module selector blocklist.
888+
bool useModuleSelectors = Opts.UseModuleSelectors;
889+
if (useModuleSelectors && M->getASTContext().blockListConfig
890+
.hasBlockListAction(M->getNameStr(), BlockListKeyKind::ModuleName,
891+
BlockListAction::
892+
DisableModuleSelectorsInModuleInterface))
893+
useModuleSelectors = false;
888894

895+
bool useExportedModuleNames = Opts.printPublicInterface();
889896
const PrintOptions printOptions = PrintOptions::printSwiftInterfaceFile(
890-
M, Opts.PreserveTypesAsWritten, Opts.PrintFullConvention,
897+
M, useModuleSelectors, Opts.PreserveTypesAsWritten,
898+
Opts.PrintFullConvention,
891899
Opts.InterfaceContentMode,
892900
useExportedModuleNames,
893901
Opts.AliasModuleNames, &aliasModuleNamesTargets);
902+
894903
InheritedProtocolCollector::PerTypeMap inheritedProtocolMap;
895904

896905
SmallVector<Decl *, 16> topLevelDecls;
@@ -909,7 +918,8 @@ bool swift::emitSwiftInterface(raw_ostream &out,
909918
D->print(out, printOptions);
910919
out << "\n";
911920

912-
diagnoseIfDeclShadowsKnownModule(Opts, const_cast<Decl *>(D), M);
921+
if (!useModuleSelectors)
922+
diagnoseIfDeclShadowsKnownModule(Opts, const_cast<Decl *>(D), M);
913923
}
914924

915925
// Print dummy extensions for any protocols that were indirectly conformed to.

0 commit comments

Comments
 (0)