Skip to content

Commit 02f0170

Browse files
authored
Merge pull request #29783 from nkcsgexi/embed-symbols-tbd
TBDGen: add a flag for embedding external symbols in emitted tbd file
2 parents 8c1a959 + e013f1f commit 02f0170

File tree

8 files changed

+62
-4
lines changed

8 files changed

+62
-4
lines changed

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,9 @@ REMARK(platform_previous_install_name, none,
284284
ERROR(unknown_platform_name, none,
285285
"unkown platform name %0", (StringRef))
286286

287+
ERROR(unknown_swift_module_name, none,
288+
"cannot find Swift module with name %0", (StringRef))
289+
287290
ERROR(cannot_find_install_name, none,
288291
"cannot find previous install name for module %0 in %1", (StringRef, StringRef))
289292

include/swift/Option/Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,9 @@ def emit_tbd_path : Separate<["-"], "emit-tbd-path">,
344344
def emit_tbd_path_EQ : Joined<["-"], "emit-tbd-path=">,
345345
Flags<[FrontendOption, NoInteractiveOption, ArgumentIsPath]>,
346346
Alias<emit_tbd_path>;
347+
def embed_tbd_for_module : Separate<["-"], "embed-tbd-for-module">,
348+
Flags<[FrontendOption]>,
349+
HelpText<"Embed symbols from the module in the emitted tbd file">;
347350

348351
def serialize_diagnostics : Flag<["-"], "serialize-diagnostics">,
349352
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>,

include/swift/TBDGen/TBDGen.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ struct TBDGenOptions {
5353
/// The path to a Json file indicating the module name to install-name map
5454
/// used by @_originallyDefinedIn
5555
std::string ModuleInstallNameMapPath;
56+
57+
/// For these modules, TBD gen should embed their symbols in the emitted tbd
58+
/// file.
59+
/// Typically, these modules are static linked libraries. Thus their symbols
60+
/// are embeded in the current dylib.
61+
std::vector<std::string> embedSymbolsFromModules;
5662
};
5763

5864
void enumeratePublicSymbols(FileUnit *module, llvm::StringSet<> &symbols,

lib/Driver/ToolChains.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,9 @@ static void addCommonFrontendArgs(const ToolChain &TC, const OutputInfo &OI,
264264
// Pass through the values passed to -Xfrontend.
265265
inputArgs.AddAllArgValues(arguments, options::OPT_Xfrontend);
266266

267+
// Pass on module names whose symbols should be embeded in tbd.
268+
inputArgs.AddAllArgs(arguments, options::OPT_embed_tbd_for_module);
269+
267270
if (auto *A = inputArgs.getLastArg(options::OPT_working_directory)) {
268271
// Add -Xcc -working-directory before any other -Xcc options to ensure it is
269272
// overridden by an explicit -Xcc -working-directory, although having a

lib/Frontend/CompilerInvocation.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,6 +1105,9 @@ static bool ParseTBDGenArgs(TBDGenOptions &Opts, ArgList &Args,
11051105
if (const Arg *A = Args.getLastArg(OPT_previous_module_installname_map_file)) {
11061106
Opts.ModuleInstallNameMapPath = A->getValue();
11071107
}
1108+
for (auto A : Args.getAllArgValues(OPT_embed_tbd_for_module)) {
1109+
Opts.embedSymbolsFromModules.push_back(StringRef(A).str());
1110+
}
11081111
return false;
11091112
}
11101113

lib/FrontendTool/FrontendTool.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1435,11 +1435,14 @@ static bool validateTBDIfNeeded(const CompilerInvocation &Invocation,
14351435
}
14361436

14371437
const bool allSymbols = mode == FrontendOptions::TBDValidationMode::All;
1438+
// We should ignore embeded symbols from external modules for validation.
1439+
TBDGenOptions Opts = Invocation.getTBDGenOptions();
1440+
Opts.embedSymbolsFromModules.clear();
14381441
return MSF.is<SourceFile *>()
14391442
? validateTBD(MSF.get<SourceFile *>(), IRModule,
1440-
Invocation.getTBDGenOptions(), allSymbols)
1443+
Opts, allSymbols)
14411444
: validateTBD(MSF.get<ModuleDecl *>(), IRModule,
1442-
Invocation.getTBDGenOptions(), allSymbols);
1445+
Opts, allSymbols);
14431446
}
14441447

14451448
static bool generateCode(const CompilerInvocation &Invocation,

lib/TBDGen/TBDGen.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,9 +1005,25 @@ static void enumeratePublicSymbolsAndWrite(ModuleDecl *M, FileUnit *singleFile,
10051005
assert(M == singleFile->getParentModule() && "mismatched file and module");
10061006
visitFile(singleFile);
10071007
} else {
1008-
for (auto *file : M->getFiles()) {
1009-
visitFile(file);
1008+
llvm::SmallVector<ModuleDecl*, 4> Modules;
1009+
Modules.push_back(M);
1010+
for (auto Name: opts.embedSymbolsFromModules) {
1011+
if (auto *MD = ctx.getModuleByName(Name)) {
1012+
// If it is a clang module, the symbols should be collected by TAPI.
1013+
if (!MD->isNonSwiftModule()) {
1014+
Modules.push_back(MD);
1015+
continue;
1016+
}
1017+
}
1018+
// Diagnose module name that cannot be found
1019+
ctx.Diags.diagnose(SourceLoc(), diag::unknown_swift_module_name, Name);
10101020
}
1021+
// Collect symbols in each module.
1022+
llvm::for_each(Modules, [&](ModuleDecl *M) {
1023+
for (auto *file : M->getFiles()) {
1024+
visitFile(file);
1025+
}
1026+
});
10111027
}
10121028

10131029
if (os) {

test/TBD/embed-symbol.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// REQUIRES: VENDOR=apple
2+
// RUN: %empty-directory(%t)
3+
4+
// RUN: echo 'public class Foo {}' > %t/foo.swift
5+
// RUN: echo 'public class Bar {}' > %t/bar.swift
6+
// RUN: %target-swift-frontend -emit-module %t/foo.swift -emit-module-path %t/foo.swiftmodule
7+
// RUN: %target-swift-frontend -emit-module %t/bar.swift -emit-module-path %t/bar.swiftmodule
8+
// RUN: %target-swift-frontend -typecheck %s -emit-tbd -emit-tbd-path %t/flag-not-provided.tbd -I %t -module-name main
9+
// RUN: %FileCheck %s --check-prefix FLAG-NOT-PROVIDED < %t/flag-not-provided.tbd
10+
11+
// RUN: %target-swift-frontend -typecheck %s -emit-tbd -emit-tbd-path %t/flag-provided.tbd -I %t -embed-tbd-for-module foo -embed-tbd-for-module bar -module-name main
12+
// RUN: %FileCheck %s --check-prefix FLAG-PROVIDED < %t/flag-provided.tbd
13+
14+
import foo
15+
import bar
16+
17+
// FLAG-NOT-PROVIDED-NOT: $s3bar3BarCMa
18+
// FLAG-NOT-PROVIDED-NOT: $s3foo3FooCMa
19+
20+
// FLAG-PROVIDED: $s3bar3BarCMa
21+
// FLAG-PROVIDED: $s3foo3FooCMa

0 commit comments

Comments
 (0)