Skip to content

Commit 133e8a1

Browse files
committed
ModuleInterface: preserve AutolinkForceLoad option when generating .swiftmodule from .swiftinterface
This change ensures using .swiftmodule built from source has the same behavior as using .swiftmodule built from .swiftinterface. A swift-ide-test utility is added to print linked libraries from a Swift module for testing purposes. rdar://58057556
1 parent d903ca9 commit 133e8a1

File tree

3 files changed

+87
-1
lines changed

3 files changed

+87
-1
lines changed

Diff for: lib/Frontend/ModuleInterfaceBuilder.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,8 @@ bool ModuleInterfaceBuilder::buildSwiftModule(
348348
std::string OutPathStr = OutPath;
349349
SerializationOpts.OutputPath = OutPathStr.c_str();
350350
SerializationOpts.ModuleLinkName = FEOpts.ModuleLinkName;
351+
SerializationOpts.AutolinkForceLoad =
352+
!subInvocation.getIRGenOptions().ForceLoadSymbolName.empty();
351353

352354
// Record any non-SDK module interface files for the debug info.
353355
StringRef SDKPath = SubInstance.getASTContext().SearchPathOpts.SDKPath;

Diff for: test/ModuleInterface/force-load-autolink.swift

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -typecheck -module-name Foo -emit-module-interface-path %t/Foo.swiftinterface %s -module-link-name Foo -enable-library-evolution -autolink-force-load
3+
// RUN: %target-swift-frontend -compile-module-from-interface -o %t/Foo.swiftmodule %t/Foo.swiftinterface
4+
// RUN: %target-swift-ide-test -print-module-metadata -module-to-print Foo -I %t -source-filename %s | %FileCheck %s
5+
6+
public func foo() {}
7+
8+
// CHECK: link library: Foo, force load: true

Diff for: tools/swift-ide-test/swift-ide-test.cpp

+77-1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ enum class ActionType {
8686
PrintASTNotTypeChecked,
8787
PrintASTTypeChecked,
8888
PrintModule,
89+
PrintModuleMetadata,
8990
PrintHeader,
9091
PrintSwiftFileInterface,
9192
PrintDecl,
@@ -181,6 +182,8 @@ Action(llvm::cl::desc("Mode:"), llvm::cl::init(ActionType::None),
181182
"print-ast-typechecked", "Print the typechecked AST"),
182183
clEnumValN(ActionType::PrintModule,
183184
"print-module", "Print visible declarations in a module"),
185+
clEnumValN(ActionType::PrintModuleMetadata,
186+
"print-module-metadata", "Print meta-data in a module"),
184187
clEnumValN(ActionType::PrintHeader,
185188
"print-header", "Print visible declarations in a header file"),
186189
clEnumValN(ActionType::PrintSwiftFileInterface,
@@ -2037,6 +2040,76 @@ static int doPrintModuleGroups(const CompilerInvocation &InitInvok,
20372040
return ExitCode;
20382041
}
20392042

2043+
static void printModuleMetadata(ModuleDecl *MD) {
2044+
auto &OS = llvm::outs();
2045+
MD->collectLinkLibraries([&](LinkLibrary lib) {
2046+
OS << "link library: " << lib.getName()
2047+
<< ", force load: " << (lib.shouldForceLoad() ? "true" : "false") << "\n";
2048+
});
2049+
}
2050+
2051+
static int doPrintModuleMetaData(const CompilerInvocation &InitInvok,
2052+
const std::vector<std::string> ModulesToPrint) {
2053+
CompilerInvocation Invocation(InitInvok);
2054+
2055+
CompilerInstance CI;
2056+
// Display diagnostics to stderr.
2057+
PrintingDiagnosticConsumer PrintDiags;
2058+
CI.addDiagnosticConsumer(&PrintDiags);
2059+
if (CI.setup(Invocation))
2060+
return 1;
2061+
registerIDERequestFunctions(CI.getASTContext().evaluator);
2062+
auto &Context = CI.getASTContext();
2063+
2064+
// Load standard library so that Clang importer can use it.
2065+
auto *Stdlib = getModuleByFullName(Context, Context.StdlibModuleName);
2066+
if (!Stdlib) {
2067+
llvm::errs() << "Failed loading stdlib\n";
2068+
return 1;
2069+
}
2070+
int ExitCode = 0;
2071+
for (StringRef ModuleToPrint : ModulesToPrint) {
2072+
if (ModuleToPrint.empty()) {
2073+
ExitCode = 1;
2074+
continue;
2075+
}
2076+
2077+
// Get the (sub)module to print.
2078+
auto *M = getModuleByFullName(Context, ModuleToPrint);
2079+
if (!M) {
2080+
llvm::errs() << "error: could not find module '" << ModuleToPrint
2081+
<< "'\n";
2082+
ExitCode = 1;
2083+
continue;
2084+
}
2085+
2086+
// Split the module path.
2087+
std::vector<StringRef> ModuleName;
2088+
while (!ModuleToPrint.empty()) {
2089+
StringRef SubModuleName;
2090+
std::tie(SubModuleName, ModuleToPrint) = ModuleToPrint.split('.');
2091+
ModuleName.push_back(SubModuleName);
2092+
}
2093+
assert(!ModuleName.empty());
2094+
2095+
// FIXME: If ModuleToPrint is a submodule, get its top-level module, which
2096+
// will be the DeclContext for all of its Decls since we don't have first-
2097+
// class submodules.
2098+
if (ModuleName.size() > 1) {
2099+
M = getModuleByFullName(Context, ModuleName[0]);
2100+
if (!M) {
2101+
llvm::errs() << "error: could not find module '" << ModuleName[0]
2102+
<< "'\n";
2103+
ExitCode = 1;
2104+
continue;
2105+
}
2106+
}
2107+
printModuleMetadata(M);
2108+
}
2109+
2110+
return ExitCode;
2111+
}
2112+
20402113
static int doPrintModules(const CompilerInvocation &InitInvok,
20412114
const std::vector<std::string> ModulesToPrint,
20422115
const std::vector<std::string> GroupsToPrint,
@@ -3543,7 +3616,10 @@ int main(int argc, char *argv[]) {
35433616
}
35443617
break;
35453618
}
3546-
3619+
case ActionType::PrintModuleMetadata: {
3620+
ExitCode = doPrintModuleMetaData(InitInvok, options::ModuleToPrint);
3621+
break;
3622+
}
35473623
case ActionType::PrintHeader: {
35483624
ExitCode = doPrintHeaders(
35493625
InitInvok, options::HeaderToPrint, PrintOpts,

0 commit comments

Comments
 (0)