Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions include/swift/AST/PrintOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,9 @@ struct PrintOptions {
/// with types sharing a name with a module.
bool AliasModuleNames = false;

/// Use module selectors when printing names.
bool UseModuleSelectors = false;

/// Name of the modules that have been aliased in AliasModuleNames mode.
/// Ideally we would use something other than a string to identify a module,
/// but since one alias can apply to more than one module, strings happen
Expand Down Expand Up @@ -769,6 +772,7 @@ struct PrintOptions {
///
/// \see swift::emitSwiftInterface
static PrintOptions printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
bool useModuleSelectors,
bool preferTypeRepr,
bool printFullConvention,
InterfaceMode interfaceMode,
Expand Down
1 change: 1 addition & 0 deletions include/swift/Basic/BlockListAction.def
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ BLOCKLIST_ACTION(ShouldDisableOwnershipVerification)
BLOCKLIST_ACTION(SkipEmittingFineModuleTrace)
BLOCKLIST_ACTION(SkipIndexingModule)
BLOCKLIST_ACTION(ShouldUseTypeCheckerPerfHacks)
BLOCKLIST_ACTION(DisableModuleSelectorsInModuleInterface)

#undef BLOCKLIST_ACTION
3 changes: 2 additions & 1 deletion include/swift/Frontend/ModuleInterfaceLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,8 @@ struct InterfaceSubContextDelegateImpl : InterfaceSubContextDelegate {
const LangOptions &LangOpts,
const ClangImporterOptions &clangImporterOpts,
const CASOptions &casOpts,
bool suppressNotes, bool suppressRemarks);
bool suppressNotes, bool suppressRemarks,
PrintDiagnosticNamesMode diagnosticNamesMode);
bool extractSwiftInterfaceVersionAndArgs(CompilerInvocation &subInvocation,
DiagnosticEngine &subInstanceDiags,
SwiftInterfaceInfo &interfaceInfo,
Expand Down
3 changes: 3 additions & 0 deletions include/swift/Frontend/ModuleInterfaceSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ struct ModuleInterfaceOptions {
/// with types sharing a name with a module.
bool AliasModuleNames = false;

/// Should we emit module selectors into the module interface?
bool UseModuleSelectors = false;

/// See \ref FrontendOptions.PrintFullConvention.
/// [TODO: Clang-type-plumbing] This check should go away.
bool PrintFullConvention = false;
Expand Down
10 changes: 10 additions & 0 deletions include/swift/Option/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,16 @@ def emit_variant_package_module_interface_path :
MetaVarName<"<path>">,
HelpText<"Output package module interface file for the target variant to <path>">;

def enable_module_selectors_in_module_interface :
Flag<["-"], "enable-module-selectors-in-module-interface">,
Flags<[FrontendOption, NoInteractiveOption]>,
HelpText<"When emitting module interface files, use module selectors to avoid name collisions">;

def disable_module_selectors_in_module_interface :
Flag<["-"], "disable-module-selectors-in-module-interface">,
Flags<[FrontendOption, NoInteractiveOption]>,
HelpText<"When emitting module interface files, do not use module selectors to avoid name collisions">;

def verify_emitted_module_interface :
Flag<["-"], "verify-emitted-module-interface">,
Flags<[NoInteractiveOption, DoesNotAffectIncrementalBuild]>,
Expand Down
63 changes: 52 additions & 11 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ struct PrintWithOpaqueResultTypeKeywordRAII {
};

PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
bool useModuleSelectors,
bool preferTypeRepr,
bool printFullConvention,
InterfaceMode interfaceMode,
Expand All @@ -276,6 +277,7 @@ PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
result.PrintLongAttrsOnSeparateLines = true;
result.TypeDefinitions = true;
result.CurrentModule = ModuleToPrint;
result.UseModuleSelectors = useModuleSelectors;
result.FullyQualifiedTypes = true;
result.FullyQualifiedTypesIfAmbiguous = true;
result.FullyQualifiedExtendedTypesIfAmbiguous = true;
Expand Down Expand Up @@ -6058,9 +6060,8 @@ class TypePrinter : public TypeVisitor<TypePrinter, void, NonRecursivePrintOptio
return Options.CurrentModule->getVisibleClangModules(Options.InterfaceContentKind);
}

template <typename T>
void printModuleContext(T *Ty) {
FileUnit *File = cast<FileUnit>(Ty->getDecl()->getModuleScopeContext());
void printModuleContext(GenericTypeDecl *TyDecl) {
FileUnit *File = cast<FileUnit>(TyDecl->getModuleScopeContext());
ModuleDecl *Mod = File->getParentModule();
StringRef ExportedModuleName = File->getExportedModuleName();

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

if (Options.UseOriginallyDefinedInModuleNames) {
Decl *D = Ty->getDecl();
for (auto attr: D->getAttrs().getAttributes<OriginallyDefinedInAttr>()) {
if (auto attr =
TyDecl->getAttrs().getAttribute<OriginallyDefinedInAttr>()) {
Name = Mod->getASTContext().getIdentifier(
const_cast<OriginallyDefinedInAttr *>(attr)
->getManglingModuleName());
break;
attr->getManglingModuleName());
}
}

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

Printer.printModuleRef(Mod, Name);
Printer << ".";
}

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

bool isMemberOfGenericParameter(TypeBase *T) {
Type parent = nullptr;
if (auto alias = dyn_cast<TypeAliasType>(T))
parent = alias->getParent();
else if (auto generic = T->getAs<AnyGenericType>())
parent = generic->getParent();
return parent && parent->isTypeParameter();
}

bool shouldPrintModuleSelector(TypeBase *T) {
if (!Options.UseModuleSelectors)
return false;

GenericTypeDecl *GTD = T->getAnyGeneric();
if (!GTD && isa<TypeAliasType>(T))
GTD = cast<TypeAliasType>(T)->getDecl();
if (!GTD)
return false;

// Builtin types must always be qualified somehow.
ModuleDecl *M = GTD->getDeclContext()->getParentModule();
if (M->isBuiltinModule())
return true;

// A member of a generic parameter can't be qualified by a module selector.
if (isMemberOfGenericParameter(T))
return false;

// Module selectors skip over local types, so don't add one.
return GTD->getLocalContext() == nullptr;
}

bool shouldPrintFullyQualified(TypeBase *T) {
if (Options.UseModuleSelectors)
return false;

if (Options.FullyQualifiedTypes)
return true;

Expand Down Expand Up @@ -6197,7 +6230,15 @@ class TypePrinter : public TypeVisitor<TypePrinter, void, NonRecursivePrintOptio
printParentType(parent);
NameContext = PrintNameContext::TypeMember;
} else if (shouldPrintFullyQualified(Ty)) {
printModuleContext(Ty);
printModuleContext(Ty->getDecl());
Printer << ".";
NameContext = PrintNameContext::TypeMember;
}

// We print module selectors whether or not we printed a parent type.
if (shouldPrintModuleSelector(Ty)) {
printModuleContext(Ty->getDecl());
Printer << "::";
NameContext = PrintNameContext::TypeMember;
}

Expand Down
2 changes: 2 additions & 0 deletions lib/Driver/ToolChains.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,8 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI,
inputArgs.AddLastArg(arguments, options::OPT_module_cache_path);
inputArgs.AddLastArg(arguments, options::OPT_module_link_name);
inputArgs.AddLastArg(arguments, options::OPT_module_abi_name);
inputArgs.AddLastArg(arguments, options::OPT_enable_module_selectors_in_module_interface,
options::OPT_disable_module_selectors_in_module_interface);
inputArgs.AddLastArg(arguments, options::OPT_package_name);
inputArgs.AddLastArg(arguments, options::OPT_export_as);
inputArgs.AddLastArg(arguments, options::OPT_nostdimport);
Expand Down
21 changes: 19 additions & 2 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,8 @@ static void PrintArg(raw_ostream &OS, const char *Arg, StringRef TempDir) {
}

static void ParseModuleInterfaceArgs(ModuleInterfaceOptions &Opts,
ArgList &Args) {
ArgList &Args,
DiagnosticEngine &diags) {
using namespace options;

Opts.PreserveTypesAsWritten |=
Expand All @@ -545,6 +546,7 @@ static void ParseModuleInterfaceArgs(ModuleInterfaceOptions &Opts,
Args.hasFlag(OPT_alias_module_names_in_module_interface,
OPT_disable_alias_module_names_in_module_interface,
::getenv("SWIFT_ALIAS_MODULE_NAMES_IN_INTERFACES"));

Opts.PrintFullConvention |=
Args.hasArg(OPT_experimental_print_full_convention);
Opts.DebugPrintInvalidSyntax |=
Expand All @@ -558,6 +560,21 @@ static void ParseModuleInterfaceArgs(ModuleInterfaceOptions &Opts,
Opts.setInterfaceMode(PrintOptions::InterfaceMode::Private);
}
}

if (Args.hasArgNoClaim(OPT_enable_module_selectors_in_module_interface)
|| Args.hasArgNoClaim(OPT_disable_module_selectors_in_module_interface)) {
Opts.UseModuleSelectors =
Args.hasFlag(OPT_enable_module_selectors_in_module_interface,
OPT_disable_module_selectors_in_module_interface,
false);
} else if (auto envValue = ::getenv("SWIFT_MODULE_SELECTORS_IN_INTERFACES")) {
Opts.UseModuleSelectors = llvm::StringSwitch<bool>(envValue)
.CasesLower("false", "no", "off", "0", false)
.Default(true);
} else {
// Any heuristics we might add would go here.
Opts.UseModuleSelectors = false;
}
}

/// Checks if an arg is generally allowed to be included
Expand Down Expand Up @@ -4169,7 +4186,7 @@ bool CompilerInvocation::parseArgs(
setMainExecutablePath(mainExecutablePath);
}

ParseModuleInterfaceArgs(ModuleInterfaceOpts, ParsedArgs);
ParseModuleInterfaceArgs(ModuleInterfaceOpts, ParsedArgs, Diags);
SaveModuleInterfaceArgs(ModuleInterfaceOpts, FrontendOpts, ParsedArgs, Diags);

if (ParseCASArgs(CASOpts, ParsedArgs, Diags, FrontendOpts)) {
Expand Down
20 changes: 18 additions & 2 deletions lib/Frontend/ModuleInterfaceLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1663,7 +1663,8 @@ void InterfaceSubContextDelegateImpl::inheritOptionsForBuildingInterface(
FrontendOptions::ActionType requestedAction,
const SearchPathOptions &SearchPathOpts, const LangOptions &LangOpts,
const ClangImporterOptions &clangImporterOpts, const CASOptions &casOpts,
bool suppressNotes, bool suppressRemarks) {
bool suppressNotes, bool suppressRemarks,
PrintDiagnosticNamesMode printDiagnosticNames) {
GenericArgs.push_back("-frontend");
// Start with a genericSubInvocation that copies various state from our
// invoking ASTContext.
Expand Down Expand Up @@ -1764,6 +1765,20 @@ void InterfaceSubContextDelegateImpl::inheritOptionsForBuildingInterface(
GenericArgs.push_back("-suppress-remarks");
}

// Inherit the parent invocation's setting for printing diagnostic IDs.
genericSubInvocation.getDiagnosticOptions().PrintDiagnosticNames =
printDiagnosticNames;
switch (printDiagnosticNames) {
case PrintDiagnosticNamesMode::None:
break;
case PrintDiagnosticNamesMode::Identifier:
GenericArgs.push_back("-debug-diagnostic-names");
break;
case PrintDiagnosticNamesMode::Group:
// FIXME: Currently no flag for Group mode
break;
}

// Inherit this setting down so that it can affect error diagnostics (mostly
// by making them non-fatal).
genericSubInvocation.getLangOptions().DebuggerSupport = LangOpts.DebuggerSupport;
Expand Down Expand Up @@ -1870,7 +1885,8 @@ InterfaceSubContextDelegateImpl::InterfaceSubContextDelegateImpl(
inheritOptionsForBuildingInterface(LoaderOpts.requestedAction, searchPathOpts,
langOpts, clangImporterOpts, casOpts,
Diags->getSuppressNotes(),
Diags->getSuppressRemarks());
Diags->getSuppressRemarks(),
Diags->getPrintDiagnosticNamesMode());
// Configure front-end input.
auto &SubFEOpts = genericSubInvocation.getFrontendOptions();
SubFEOpts.RequestedAction = LoaderOpts.requestedAction;
Expand Down
16 changes: 13 additions & 3 deletions lib/Frontend/ModuleInterfaceSupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -884,13 +884,22 @@ bool swift::emitSwiftInterface(raw_ostream &out,

printImports(out, Opts, M, aliasModuleNamesTargets);

bool useExportedModuleNames = Opts.printPublicInterface();
// Apply module selector blocklist.
bool useModuleSelectors = Opts.UseModuleSelectors;
if (useModuleSelectors && M->getASTContext().blockListConfig
.hasBlockListAction(M->getNameStr(), BlockListKeyKind::ModuleName,
BlockListAction::
DisableModuleSelectorsInModuleInterface))
useModuleSelectors = false;

bool useExportedModuleNames = Opts.printPublicInterface();
const PrintOptions printOptions = PrintOptions::printSwiftInterfaceFile(
M, Opts.PreserveTypesAsWritten, Opts.PrintFullConvention,
M, useModuleSelectors, Opts.PreserveTypesAsWritten,
Opts.PrintFullConvention,
Opts.InterfaceContentMode,
useExportedModuleNames,
Opts.AliasModuleNames, &aliasModuleNamesTargets);

InheritedProtocolCollector::PerTypeMap inheritedProtocolMap;

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

diagnoseIfDeclShadowsKnownModule(Opts, const_cast<Decl *>(D), M);
if (!useModuleSelectors)
diagnoseIfDeclShadowsKnownModule(Opts, const_cast<Decl *>(D), M);
}

// Print dummy extensions for any protocols that were indirectly conformed to.
Expand Down
4 changes: 4 additions & 0 deletions test/ModuleInterface/Inputs/module_selector/blocklist.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
DisableModuleSelectorsInModuleInterface:
ModuleName:
- TestCase
Loading