Skip to content

Commit e550944

Browse files
authored
Merge pull request #61941 from xymus/module-alias-disambiguate
[ModuleInterface] Avoid ambiguities in swiftinterfaces by writing aliases for module names
2 parents 9c321c0 + 66586b5 commit e550944

19 files changed

+226
-26
lines changed

include/swift/AST/ASTPrinter.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
#include "llvm/Support/raw_ostream.h"
2525
#include "swift/AST/PrintOptions.h"
2626

27+
// Prefix to use when printing module names in module interfaces to avoid
28+
// ambiguities with type names, in AliasModuleNames mode.
29+
#define MODULE_DISAMBIGUATING_PREFIX "Module___"
30+
2731
namespace swift {
2832
class Decl;
2933
class DeclContext;
@@ -162,7 +166,8 @@ class ASTPrinter {
162166
PrintNameContext NameContext = PrintNameContext::Normal);
163167

164168
/// Called when printing the referenced name of a module.
165-
virtual void printModuleRef(ModuleEntity Mod, Identifier Name);
169+
virtual void printModuleRef(ModuleEntity Mod, Identifier Name,
170+
const PrintOptions &Options);
166171

167172
/// Called before printing a synthesized extension.
168173
virtual void printSynthesizedExtensionPre(const ExtensionDecl *ED,

include/swift/AST/PrintOptions.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,10 @@ struct PrintOptions {
466466
/// of the alias.
467467
bool PrintTypeAliasUnderlyingType = false;
468468

469+
/// Use aliases when printing references to modules to avoid ambiguities
470+
/// with types sharing a name with a module.
471+
bool AliasModuleNames = false;
472+
469473
/// When printing an Optional<T>, rather than printing 'T?', print
470474
/// 'T!'. Used as a modifier only when we know we're printing
471475
/// something that was declared as an implicitly unwrapped optional
@@ -601,7 +605,7 @@ struct PrintOptions {
601605
return result;
602606
}
603607

604-
/// Retrieve the set of options suitable for interface generation.
608+
/// Retrieve the set of options suitable for IDE interface generation.
605609
static PrintOptions printInterface(bool printFullConvention) {
606610
PrintOptions result =
607611
printForDiagnostics(AccessLevel::Public, printFullConvention);
@@ -636,7 +640,8 @@ struct PrintOptions {
636640
static PrintOptions printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
637641
bool preferTypeRepr,
638642
bool printFullConvention,
639-
bool printSPIs);
643+
bool printSPIs,
644+
bool aliasModuleNames);
640645

641646
/// Retrieve the set of options suitable for "Generated Interfaces", which
642647
/// are a prettified representation of the public API of a module, to be

include/swift/Frontend/ModuleInterfaceSupport.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ struct ModuleInterfaceOptions {
3333
/// interface, or should we fully-qualify them?
3434
bool PreserveTypesAsWritten = false;
3535

36+
/// Use aliases when printing references to modules to avoid ambiguities
37+
/// with types sharing a name with a module.
38+
bool AliasModuleNames = false;
39+
3640
/// See \ref FrontendOptions.PrintFullConvention.
3741
/// [TODO: Clang-type-plumbing] This check should go away.
3842
bool PrintFullConvention = false;

include/swift/Option/FrontendOptions.td

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,15 @@ def module_interface_preserve_types_as_written :
904904
HelpText<"When emitting a module interface, preserve types as they were "
905905
"written in the source">;
906906

907+
def alias_module_names_in_module_interface :
908+
Flag<["-"], "alias-module-names-in-module-interface">,
909+
HelpText<"When emitting a module interface, disambiguate modules using "
910+
"distinct alias names">;
911+
def disable_alias_module_names_in_module_interface :
912+
Flag<["-"], "disable-alias-module-names-in-module-interface">,
913+
HelpText<"When emitting a module interface, disable disambiguating modules "
914+
"using distinct alias names">;
915+
907916
def experimental_spi_imports :
908917
Flag<["-"], "experimental-spi-imports">,
909918
HelpText<"Enable experimental support for SPI imports">;

lib/AST/ASTPrinter.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ static bool contributesToParentTypeStorage(const AbstractStorageDecl *ASD) {
131131
PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
132132
bool preferTypeRepr,
133133
bool printFullConvention,
134-
bool printSPIs) {
134+
bool printSPIs,
135+
bool aliasModuleNames) {
135136
PrintOptions result;
136137
result.IsForSwiftInterface = true;
137138
result.PrintLongAttrsOnSeparateLines = true;
@@ -152,6 +153,7 @@ PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
152153
result.OpaqueReturnTypePrinting =
153154
OpaqueReturnTypePrintingMode::StableReference;
154155
result.PreferTypeRepr = preferTypeRepr;
156+
result.AliasModuleNames = aliasModuleNames;
155157
if (printFullConvention)
156158
result.PrintFunctionRepresentationAttrs =
157159
PrintOptions::FunctionRepresentationMode::Full;
@@ -365,7 +367,11 @@ void ASTPrinter::printTypeRef(Type T, const TypeDecl *RefTo, Identifier Name,
365367
printName(Name, Context);
366368
}
367369

368-
void ASTPrinter::printModuleRef(ModuleEntity Mod, Identifier Name) {
370+
void ASTPrinter::printModuleRef(ModuleEntity Mod, Identifier Name,
371+
const PrintOptions &Options) {
372+
if (Options.AliasModuleNames)
373+
printTextImpl(MODULE_DISAMBIGUATING_PREFIX);
374+
369375
printName(Name);
370376
}
371377

@@ -2493,7 +2499,7 @@ void PrintAST::visitImportDecl(ImportDecl *decl) {
24932499
Name = Declaring->getRealName();
24942500
}
24952501
}
2496-
Printer.printModuleRef(Mods.front(), Name);
2502+
Printer.printModuleRef(Mods.front(), Name, Options);
24972503
Mods = Mods.slice(1);
24982504
} else {
24992505
Printer << Elem.Item.str();
@@ -5381,7 +5387,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
53815387
}
53825388
}
53835389

5384-
Printer.printModuleRef(Mod, Name);
5390+
Printer.printModuleRef(Mod, Name, Options);
53855391
Printer << ".";
53865392
}
53875393

@@ -5728,7 +5734,8 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
57285734
Printer << "module<";
57295735
// Should print the module real name in case module aliasing is
57305736
// used (see -module-alias), since that's the actual binary name.
5731-
Printer.printModuleRef(T->getModule(), T->getModule()->getRealName());
5737+
Printer.printModuleRef(T->getModule(), T->getModule()->getRealName(),
5738+
Options);
57325739
Printer << ">";
57335740
}
57345741

lib/AST/TypeRepr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ void ComponentIdentTypeRepr::printImpl(ASTPrinter &Printer,
269269
const PrintOptions &Opts) const {
270270
if (auto *TD = dyn_cast_or_null<TypeDecl>(getBoundDecl())) {
271271
if (auto MD = dyn_cast<ModuleDecl>(TD))
272-
Printer.printModuleRef(MD, getNameRef().getBaseIdentifier());
272+
Printer.printModuleRef(MD, getNameRef().getBaseIdentifier(), Opts);
273273
else
274274
Printer.printTypeRef(Type(), TD, getNameRef().getBaseIdentifier());
275275
} else {

lib/ClangImporter/ClangImporter.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,20 +1926,26 @@ bool ClangImporter::canImportModule(ImportPath::Module modulePath,
19261926
ModuleDecl *ClangImporter::Implementation::loadModuleClang(
19271927
SourceLoc importLoc, ImportPath::Module path) {
19281928
auto &clangHeaderSearch = getClangPreprocessor().getHeaderSearchInfo();
1929+
auto realModuleName = SwiftContext.getRealModuleName(path.front().Item).str();
19291930

19301931
// Look up the top-level module first, to see if it exists at all.
19311932
clang::Module *clangModule = clangHeaderSearch.lookupModule(
1932-
path.front().Item.str(), /*ImportLoc=*/clang::SourceLocation(),
1933+
realModuleName, /*ImportLoc=*/clang::SourceLocation(),
19331934
/*AllowSearch=*/true, /*AllowExtraModuleMapSearch=*/true);
19341935
if (!clangModule)
19351936
return nullptr;
19361937

19371938
// Convert the Swift import path over to a Clang import path.
19381939
SmallVector<std::pair<clang::IdentifierInfo *, clang::SourceLocation>, 4>
19391940
clangPath;
1941+
bool isTopModuleComponent = true;
19401942
for (auto component : path) {
1943+
StringRef item = isTopModuleComponent? realModuleName:
1944+
component.Item.str();
1945+
isTopModuleComponent = false;
1946+
19411947
clangPath.emplace_back(
1942-
getClangPreprocessor().getIdentifierInfo(component.Item.str()),
1948+
getClangPreprocessor().getIdentifierInfo(item),
19431949
exportSourceLoc(component.Loc));
19441950
}
19451951

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -755,15 +755,12 @@ bool ModuleAliasesConverter::computeModuleAliases(std::vector<std::string> args,
755755
if (!allowModuleName) {
756756
if (value == options.ModuleName ||
757757
value == options.ModuleABIName ||
758-
value == options.ModuleLinkName) {
758+
value == options.ModuleLinkName ||
759+
value == STDLIB_NAME) {
759760
diags.diagnose(SourceLoc(), diag::error_module_alias_forbidden_name, value);
760761
return false;
761762
}
762763
}
763-
if (value == STDLIB_NAME) {
764-
diags.diagnose(SourceLoc(), diag::error_module_alias_forbidden_name, value);
765-
return false;
766-
}
767764
if (!Lexer::isIdentifier(value)) {
768765
diags.diagnose(SourceLoc(), diag::error_bad_module_name, value, false);
769766
return false;

lib/Frontend/CompilerInvocation.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,10 @@ static void ParseModuleInterfaceArgs(ModuleInterfaceOptions &Opts,
368368

369369
Opts.PreserveTypesAsWritten |=
370370
Args.hasArg(OPT_module_interface_preserve_types_as_written);
371+
Opts.AliasModuleNames |=
372+
Args.hasFlag(OPT_alias_module_names_in_module_interface,
373+
OPT_disable_alias_module_names_in_module_interface,
374+
false);
371375
Opts.PrintFullConvention |=
372376
Args.hasArg(OPT_experimental_print_full_convention);
373377
Opts.ExperimentalSPIImports |=

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1027,9 +1027,10 @@ class ModuleInterfaceLoaderImpl {
10271027
}
10281028
// Set up a builder if we need to build the module. It'll also set up
10291029
// the genericSubInvocation we'll need to use to compute the cache paths.
1030+
Identifier realName = ctx.getRealModuleName(ctx.getIdentifier(moduleName));
10301031
ImplicitModuleInterfaceBuilder builder(
10311032
ctx.SourceMgr, diagsToUse,
1032-
astDelegate, interfacePath, moduleName, cacheDir,
1033+
astDelegate, interfacePath, realName.str(), cacheDir,
10331034
prebuiltCacheDir, backupInterfaceDir, StringRef(),
10341035
Opts.disableInterfaceLock,
10351036
ctx.IgnoreAdjacentModules, diagnosticLoc,

0 commit comments

Comments
 (0)