Skip to content

Commit 2a28fed

Browse files
committed
Allow one to separately specify the ABI name of a module.
Introduce a new compiler flag `-module-abi-name <name>` that uses the given name as the ABI name for the module (rather than the module's name in source code). The ABI name impacts name mangling and metadata.
1 parent 6f4f9f8 commit 2a28fed

22 files changed

+111
-7
lines changed

include/swift/AST/Module.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,9 @@ class ModuleDecl : public DeclContext, public TypeDecl {
166166
friend class DirectOperatorLookupRequest;
167167
friend class DirectPrecedenceGroupLookupRequest;
168168

169+
/// The ABI name of the module, if it differs from the module name.
170+
Identifier ModuleABIName;
171+
169172
public:
170173
/// Produces the components of a given module's full name in reverse order.
171174
///
@@ -343,6 +346,17 @@ class ModuleDecl : public DeclContext, public TypeDecl {
343346
void getDeclaredCrossImportBystanders(
344347
SmallVectorImpl<Identifier> &bystanderNames);
345348

349+
/// Retrieve the ABI name of the module, which is used for metadata and
350+
/// mangling.
351+
Identifier getABIName() const {
352+
return ModuleABIName.empty() ? getName() : ModuleABIName;
353+
}
354+
355+
/// Set the ABI name of the module;
356+
void setABIName(Identifier name) {
357+
ModuleABIName = name;
358+
}
359+
346360
private:
347361
/// A cache of this module's underlying module and required bystander if it's
348362
/// an underscored cross-import overlay.

include/swift/Frontend/FrontendOptions.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,13 @@ class FrontendOptions {
4848
/// An Objective-C header to import and make implicitly visible.
4949
std::string ImplicitObjCHeaderPath;
5050

51-
/// The name of the module which the frontend is building.
51+
/// The name of the module that the frontend is building.
5252
std::string ModuleName;
5353

54+
/// The ABI name of the module that the frontend is building, to be used in
55+
/// mangling and metadata.
56+
std::string ModuleABIName;
57+
5458
/// The name of the library to link against when using this module.
5559
std::string ModuleLinkName;
5660

include/swift/Option/Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,9 @@ def module_link_name_EQ : Joined<["-"], "module-link-name=">,
421421
def autolink_force_load : Flag<["-"], "autolink-force-load">,
422422
Flags<[FrontendOption, ModuleInterfaceOption, HelpHidden]>,
423423
HelpText<"Force ld to link against this module even if no symbols are used">;
424+
def module_abi_name : Separate<["-"], "module-abi-name">,
425+
Flags<[FrontendOption, ModuleInterfaceOption]>,
426+
HelpText<"ABI name to use for the contents of this module">;
424427

425428
def emit_module : Flag<["-"], "emit-module">,
426429
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild,

include/swift/Serialization/Validation.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ struct ValidationInfo {
9393
class ExtendedValidationInfo {
9494
SmallVector<StringRef, 4> ExtraClangImporterOpts;
9595
StringRef SDKPath;
96+
StringRef ModuleABIName;
9697
struct {
9798
unsigned ArePrivateImportsEnabled : 1;
9899
unsigned IsSIB : 1;
@@ -145,6 +146,9 @@ class ExtendedValidationInfo {
145146
void setAllowModuleWithCompilerErrorsEnabled(bool val) {
146147
Bits.IsAllowModuleWithCompilerErrorsEnabled = val;
147148
}
149+
150+
StringRef getModuleABIName() const { return ModuleABIName; }
151+
void setModuleABIName(StringRef name) { ModuleABIName = name; }
148152
};
149153

150154
/// Returns info about the serialized AST in the given data.

lib/AST/ASTContext.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ struct ASTContext::Implementation {
164164
/// DenseMap.
165165
llvm::MapVector<Identifier, ModuleDecl *> LoadedModules;
166166

167+
/// The set of top-level modules we have loaded, indexed by ABI name.
168+
llvm::MapVector<Identifier, ModuleDecl *> LoadedModulesByABIName;
169+
167170
// FIXME: This is a StringMap rather than a StringSet because StringSet
168171
// doesn't allow passing in a pre-existing allocator.
169172
llvm::StringMap<Identifier::Aligner, llvm::BumpPtrAllocator&>

lib/AST/ASTMangler.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2143,13 +2143,15 @@ void ASTMangler::appendModule(const ModuleDecl *module,
21432143
StringRef useModuleName) {
21442144
assert(!module->getParent() && "cannot mangle nested modules!");
21452145

2146+
StringRef ModName =
2147+
DWARFMangling ? module->getName().str() : module->getABIName().str();
2148+
21462149
// Try the special 'swift' substitution.
2147-
if (module->isStdlibModule()) {
2150+
if (ModName == STDLIB_NAME) {
21482151
assert(useModuleName.empty());
21492152
return appendOperator("s");
21502153
}
21512154

2152-
StringRef ModName = module->getName().str();
21532155
if (ModName == MANGLING_MODULE_OBJC) {
21542156
assert(useModuleName.empty());
21552157
return appendOperator("So");

lib/AST/Decl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,7 @@ StringRef Decl::getAlternateModuleName() const {
638638
}
639639
}
640640
}
641+
641642
for (auto *DC = getDeclContext(); DC; DC = DC->getParent()) {
642643
if (auto decl = DC->getAsDecl()) {
643644
if (decl == this)

lib/Driver/ToolChains.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI,
231231
inputArgs.AddLastArg(arguments, options::OPT_import_underlying_module);
232232
inputArgs.AddLastArg(arguments, options::OPT_module_cache_path);
233233
inputArgs.AddLastArg(arguments, options::OPT_module_link_name);
234+
inputArgs.AddLastArg(arguments, options::OPT_module_abi_name);
234235
inputArgs.AddLastArg(arguments, options::OPT_nostdimport);
235236
inputArgs.AddLastArg(arguments, options::OPT_parse_stdlib);
236237
inputArgs.AddLastArg(arguments, options::OPT_resource_dir);

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,9 @@ bool ArgsToFrontendOptionsConverter::convert(
217217
return true;
218218
}
219219

220+
if (const Arg *A = Args.getLastArg(OPT_module_abi_name))
221+
Opts.ModuleABIName = A->getValue();
222+
220223
if (const Arg *A = Args.getLastArg(OPT_module_link_name))
221224
Opts.ModuleLinkName = A->getValue();
222225

lib/Frontend/Frontend.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -925,7 +925,10 @@ ModuleDecl *CompilerInstance::getMainModule() const {
925925
MainModule->setPrivateImportsEnabled();
926926
if (Invocation.getFrontendOptions().EnableImplicitDynamic)
927927
MainModule->setImplicitDynamicEnabled();
928-
928+
if (!Invocation.getFrontendOptions().ModuleABIName.empty()) {
929+
MainModule->setABIName(getASTContext().getIdentifier(
930+
Invocation.getFrontendOptions().ModuleABIName));
931+
}
929932
if (Invocation.getFrontendOptions().EnableLibraryEvolution)
930933
MainModule->setResilienceStrategy(ResilienceStrategy::Resilient);
931934

lib/IDE/CompletionInstance.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,7 @@ bool CompletionInstance::performCachedOperationIfPossible(
464464
auto &Ctx = oldM->getASTContext();
465465
auto *newM = ModuleDecl::createMainModule(Ctx, oldM->getName(),
466466
oldM->getImplicitImportInfo());
467+
newM->setABIName(oldM->getABIName());
467468
auto *newSF = new (Ctx) SourceFile(*newM, SourceFileKind::Main, newBufferID,
468469
oldSF->getParsingOptions());
469470
newM->addFile(*newSF);

lib/IRGen/GenMeta.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ namespace {
492492
}
493493

494494
void addName() {
495-
B.addRelativeAddress(IGM.getAddrOfGlobalString(M->getName().str(),
495+
B.addRelativeAddress(IGM.getAddrOfGlobalString(M->getABIName().str(),
496496
/*willBeRelativelyAddressed*/ true));
497497
}
498498

lib/Serialization/ModuleFile.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,11 @@ class ModuleFile
433433
return Core->Name;
434434
}
435435

436+
/// The ABI name of the module.
437+
StringRef getModuleABIName() const {
438+
return Core->ModuleABIName;
439+
}
440+
436441
/// The Swift compatibility version in use when this module was built.
437442
const version::Version &getCompatibilityVersion() const {
438443
return Core->CompatibilityVersion;

lib/Serialization/ModuleFileSharedCore.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,9 @@ static bool readOptionsBlock(llvm::BitstreamCursor &cursor,
148148
case options_block::IS_ALLOW_MODULE_WITH_COMPILER_ERRORS_ENABLED:
149149
extendedInfo.setAllowModuleWithCompilerErrorsEnabled(true);
150150
break;
151+
case options_block::MODULE_ABI_NAME:
152+
extendedInfo.setModuleABIName(blobData);
153+
break;
151154
default:
152155
// Unknown options record, possibly for use by a future version of the
153156
// module format.
@@ -1177,6 +1180,7 @@ ModuleFileSharedCore::ModuleFileSharedCore(
11771180
Bits.IsAllowModuleWithCompilerErrorsEnabled =
11781181
extInfo.isAllowModuleWithCompilerErrorsEnabled();
11791182
MiscVersion = info.miscVersion;
1183+
ModuleABIName = extInfo.getModuleABIName();
11801184

11811185
hasValidControlBlock = true;
11821186
break;

lib/Serialization/ModuleFileSharedCore.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ class ModuleFileSharedCore {
7373
/// include the version string of the compiler that built the module.
7474
StringRef MiscVersion;
7575

76+
/// The module ABI name.
77+
StringRef ModuleABIName;
78+
7679
/// \c true if this module has incremental dependency information.
7780
bool HasIncrementalInfo = false;
7881

lib/Serialization/ModuleFormat.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5656
/// describe what change you made. The content of this comment isn't important;
5757
/// it just ensures a conflict if two people change the module format.
5858
/// Don't worry about adhering to the 80-column limit for this line.
59-
const uint16_t SWIFTMODULE_VERSION_MINOR = 602; // noasync apply
59+
const uint16_t SWIFTMODULE_VERSION_MINOR = 603; // module ABI name
6060

6161
/// A standard hash seed used for all string hashes in a serialized module.
6262
///
@@ -790,7 +790,8 @@ namespace options_block {
790790
RESILIENCE_STRATEGY,
791791
ARE_PRIVATE_IMPORTS_ENABLED,
792792
IS_IMPLICIT_DYNAMIC_ENABLED,
793-
IS_ALLOW_MODULE_WITH_COMPILER_ERRORS_ENABLED
793+
IS_ALLOW_MODULE_WITH_COMPILER_ERRORS_ENABLED,
794+
MODULE_ABI_NAME,
794795
};
795796

796797
using SDKPathLayout = BCRecordLayout<
@@ -828,6 +829,11 @@ namespace options_block {
828829
using IsAllowModuleWithCompilerErrorsEnabledLayout = BCRecordLayout<
829830
IS_ALLOW_MODULE_WITH_COMPILER_ERRORS_ENABLED
830831
>;
832+
833+
using ModuleABINameLayout = BCRecordLayout<
834+
MODULE_ABI_NAME,
835+
BCBlob
836+
>;
831837
}
832838

833839
/// The record types within the input block.

lib/Serialization/Serialization.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,7 @@ void Serializer::writeBlockInfoBlock() {
814814
BLOCK_RECORD(options_block, ARE_PRIVATE_IMPORTS_ENABLED);
815815
BLOCK_RECORD(options_block, RESILIENCE_STRATEGY);
816816
BLOCK_RECORD(options_block, IS_ALLOW_MODULE_WITH_COMPILER_ERRORS_ENABLED);
817+
BLOCK_RECORD(options_block, MODULE_ABI_NAME);
817818

818819
BLOCK(INPUT_BLOCK);
819820
BLOCK_RECORD(input_block, IMPORTED_MODULE);
@@ -1001,6 +1002,11 @@ void Serializer::writeHeader(const SerializationOptions &options) {
10011002
AllowErrors.emit(ScratchRecord);
10021003
}
10031004

1005+
if (M->getABIName() != M->getName()) {
1006+
options_block::ModuleABINameLayout ABIName(Out);
1007+
ABIName.emit(ScratchRecord, M->getABIName().str());
1008+
}
1009+
10041010
if (options.SerializeOptionsForDebugging) {
10051011
options_block::SDKPathLayout SDKPath(Out);
10061012
options_block::XCCLayout XCC(Out);

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,8 @@ LoadedFile *SerializedModuleLoaderBase::loadAST(
723723
M.setImplicitDynamicEnabled();
724724
if (loadedModuleFile->hasIncrementalInfo())
725725
M.setHasIncrementalInfo();
726+
if (!loadedModuleFile->getModuleABIName().empty())
727+
M.setABIName(Ctx.getIdentifier(loadedModuleFile->getModuleABIName()));
726728

727729
auto diagLocOrInvalid = diagLoc.getValueOr(SourceLoc());
728730
loadInfo.status = loadedModuleFile->associateWithFileContext(

test/IRGen/module_abi_name.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %target-swift-frontend -module-name=Hello -module-abi-name Goodbye -emit-ir %s | %FileCheck %s
2+
3+
// CHECK-NOT: {{(5|")Hello}}
4+
5+
// CHECK-DAG: [[MODULE_NAME:@.*]] = private constant [8 x i8] c"Goodbye\00"
6+
// CHECK-DAG: @"$s7GoodbyeMXM" = {{.*}} [[MODULE_NAME]]
7+
8+
// CHECK-DAG: @"$s7Goodbye8GreetingCMm" =
9+
public class Greeting { }
10+
11+
// CHECK-NOT: {{(5|")Hello}}
12+
// CHECK: define swiftcc void @"$s7Goodbye8functionyyF"()
13+
@inlinable public func function() { }
14+
15+
func callFunction() {
16+
function()
17+
}
18+
19+
// CHECK-NOT: {{(5|")Hello}}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -typecheck -emit-module-interface-path %t/Hello.swiftinterface -module-name Hello -module-abi-name Goodbye %s
3+
// RUN: %FileCheck %s < %t/Hello.swiftinterface
4+
5+
// CHECK: -module-abi-name Goodbye
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
public class Greeting { }
2+
3+
@inlinable public func function() { }
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_module_abi_name.swift -module-abi-name Goodbye
3+
// RUN: %target-swift-frontend -module-name ModuleABIName -emit-sil -I %t %s | %FileCheck %s
4+
5+
import def_module_abi_name
6+
7+
func callFunction() {
8+
// CHECK: function_ref @$s7Goodbye8functionyyF
9+
def_module_abi_name.function()
10+
}
11+
12+
// CHECK: sil [serialized] @$s7Goodbye8functionyyF : $@convention(thin) () -> ()

0 commit comments

Comments
 (0)