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
3 changes: 3 additions & 0 deletions include/swift/AST/DiagnosticsFrontend.def
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ ERROR(error_formatting_invalid_range,none,
WARNING(stats_disabled,none,
"compiler was not built with support for collecting statistics", ())

WARNING(tbd_only_supported_in_whole_module,none,
"TBD generation is only supported when the whole module can be seen", ())

ERROR(symbol_in_tbd_not_in_ir,none,
"symbol '%0' (%1) is in TBD file, but not in generated IR",
(StringRef, StringRef))
Expand Down
4 changes: 2 additions & 2 deletions include/swift/Driver/Driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,8 +374,8 @@ class Driver {
CommandOutput *Output) const;

void chooseTBDPath(Compilation &C, const OutputInfo &OI,
StringRef workingDirectory, llvm::SmallString<128> &Buf,
CommandOutput *Output) const;
const TypeToPathMap *OutputMap, StringRef workingDirectory,
llvm::SmallString<128> &Buf, CommandOutput *Output) const;

public:
/// Handle any arguments which should be treated before building actions or
Expand Down
43 changes: 25 additions & 18 deletions lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2149,11 +2149,11 @@ static bool hasExistingAdditionalOutput(CommandOutput &output,
return false;
}

static void addAuxiliaryOutput(Compilation &C, CommandOutput &output,
file_types::ID outputType, const OutputInfo &OI,
const TypeToPathMap *outputMap,
StringRef workingDirectory,
StringRef outputPath = StringRef()) {
static void addAuxiliaryOutput(
Compilation &C, CommandOutput &output, file_types::ID outputType,
const OutputInfo &OI, const TypeToPathMap *outputMap,
StringRef workingDirectory, StringRef outputPath = StringRef(),
llvm::opt::OptSpecifier requireArg = llvm::opt::OptSpecifier()) {

if (hasExistingAdditionalOutput(output, outputType, outputPath))
return;
Expand All @@ -2170,6 +2170,10 @@ static void addAuxiliaryOutput(Compilation &C, CommandOutput &output,
output.setAdditionalOutputForType(outputType, outputMapPath);
} else if (!outputPath.empty()) {
output.setAdditionalOutputForType(outputType, outputPath);
} else if (requireArg.isValid() && !C.getArgs().getLastArg(requireArg)) {
// This auxiliary output only exists if requireArg is passed, but it
// wasn't this time.
return;
} else {
// Put the auxiliary output file next to "the" primary output file.
//
Expand Down Expand Up @@ -2396,6 +2400,14 @@ Job *Driver::buildJobsForAction(Compilation &C, const JobAction *JA,
Output.get());
}

if (isa<MergeModuleJobAction>(JA) ||
(isa<CompileJobAction>(JA) &&
OI.CompilerMode == OutputInfo::Mode::SingleCompile)) {
// An emit-tbd argument gets passed down to a job that sees the whole
// module, either the -merge-modules job or a -wmo compiler invocation.
chooseTBDPath(C, OI, OutputMap, workingDirectory, Buf, Output.get());
}

if (isa<CompileJobAction>(JA))
chooseDependenciesOutputPaths(C, OI, OutputMap, workingDirectory, Buf,
Output.get());
Expand Down Expand Up @@ -2715,7 +2727,6 @@ void Driver::chooseDependenciesOutputPaths(Compilation &C, const OutputInfo &OI,
workingDirectory);
}
chooseLoadedModuleTracePath(C, OI, workingDirectory, Buf, Output);
chooseTBDPath(C, OI, workingDirectory, Buf, Output);
}

void Driver::chooseLoadedModuleTracePath(Compilation &C, const OutputInfo &OI,
Expand Down Expand Up @@ -2752,22 +2763,18 @@ void Driver::chooseLoadedModuleTracePath(Compilation &C, const OutputInfo &OI,
}

void Driver::chooseTBDPath(Compilation &C, const OutputInfo &OI,
const TypeToPathMap *OutputMap,
StringRef workingDirectory,
llvm::SmallString<128> &Buf,
CommandOutput *Output) const {
if (C.getArgs().hasArg(options::OPT_emit_tbd, options::OPT_emit_tbd_path)) {
if (OI.CompilerMode != OutputInfo::Mode::SingleCompile) {
llvm::outs() << "TBD emission has been disabled, because it requires a "
<< "single compiler invocation: consider enabling the "
<< "-whole-module-optimization flag.\n";
} else {
auto filename = *getOutputFilenameFromPathArgOrAsTopLevel(
OI, C.getArgs(), options::OPT_emit_tbd_path, file_types::TY_TBD,
/*TreatAsTopLevelOutput=*/true, workingDirectory, "tbd", Buf);

Output->setAdditionalOutputForType(file_types::TY_TBD, filename);
}
StringRef pathFromArgs;
if (const Arg *A = C.getArgs().getLastArg(options::OPT_emit_tbd_path)) {
pathFromArgs = A->getValue();
}

addAuxiliaryOutput(C, *Output, file_types::TY_TBD, OI, OutputMap,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice factoring!

workingDirectory, pathFromArgs,
/*requireArg=*/options::OPT_emit_tbd);
}

void Driver::chooseOptimizationRecordPath(Compilation &C, const OutputInfo &OI,
Expand Down
2 changes: 2 additions & 0 deletions lib/Driver/ToolChains.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,8 @@ ToolChain::constructInvocation(const MergeModuleJobAction &job,
"-serialize-diagnostics-path");
addOutputsOfType(Arguments, context.Output, context.Args,
file_types::TY_ObjCHeader, "-emit-objc-header-path");
addOutputsOfType(Arguments, context.Output, context.Args, file_types::TY_TBD,
"-emit-tbd-path");

context.Args.AddLastArg(Arguments, options::OPT_import_objc_header);

Expand Down
2 changes: 1 addition & 1 deletion lib/Frontend/Frontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ CompilerInvocation::getSerializedDiagnosticsPathForAtMostOnePrimary() const {
}
std::string CompilerInvocation::getTBDPathForWholeModule() const {
assert(getFrontendOptions().InputsAndOutputs.isWholeModule() &&
"TBDPath only makes sense in WMO mode");
"TBDPath only makes sense when the whole module can be seen");
return getPrimarySpecificPathsForAtMostOnePrimary()
.SupplementaryOutputs.TBDPath;
}
Expand Down
8 changes: 6 additions & 2 deletions lib/FrontendTool/FrontendTool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -769,9 +769,13 @@ static bool writeTBDIfNeeded(CompilerInvocation &Invocation,
if (!frontendOpts.InputsAndOutputs.hasTBDPath())
return false;

if (!frontendOpts.InputsAndOutputs.isWholeModule()) {
Instance.getDiags().diagnose(SourceLoc(),
diag::tbd_only_supported_in_whole_module);
return false;
}

const std::string &TBDPath = Invocation.getTBDPathForWholeModule();
assert(!TBDPath.empty() &&
"If not WMO, getTBDPathForWholeModule should have failed");

auto installName = frontendOpts.TBDInstallName.empty()
? "lib" + Invocation.getModuleName().str() + ".dylib"
Expand Down
28 changes: 28 additions & 0 deletions test/TBD/Inputs/multi-file-nonresilient-expected.tbd
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
$S9multifile5ClassC10staticFunc8default_ySi_tFZ
$S9multifile5ClassC8propertySivg
$S9multifile5ClassC8propertySivm
$S9multifile5ClassC8propertySivpWvd
$S9multifile5ClassC8propertySivs
$S9multifile5ClassCACycfC
$S9multifile5ClassCACycfc
$S9multifile5ClassCMa
$S9multifile5ClassCMm
$S9multifile5ClassCMn
$S9multifile5ClassCN
$S9multifile5ClassCfD
$S9multifile5ClassCfd
$S9multifile6Class2C10staticFunc8default_ySi_tFZ
$S9multifile6Class2C8propertySivg
$S9multifile6Class2C8propertySivm
$S9multifile6Class2C8propertySivpWvd
$S9multifile6Class2C8propertySivs
$S9multifile6Class2CACycfC
$S9multifile6Class2CACycfc
$S9multifile6Class2CMa
$S9multifile6Class2CMm
$S9multifile6Class2CMn
$S9multifile6Class2CN
$S9multifile6Class2CfD
$S9multifile6Class2Cfd
$S9multifile8functionyyF
$S9multifile9function2yyF
36 changes: 36 additions & 0 deletions test/TBD/Inputs/multi-file-resilient-expected.tbd
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
$S9multifile5ClassC10staticFunc8default_ySi_tFZ
$S9multifile5ClassC8propertySivg
$S9multifile5ClassC8propertySivgTj
$S9multifile5ClassC8propertySivm
$S9multifile5ClassC8propertySivmTj
$S9multifile5ClassC8propertySivs
$S9multifile5ClassC8propertySivsTj
$S9multifile5ClassCACycfC
$S9multifile5ClassCACycfc
$S9multifile5ClassCACycfcTj
$S9multifile5ClassCMa
$S9multifile5ClassCMm
$S9multifile5ClassCMn
$S9multifile5ClassCMo
$S9multifile5ClassCN
$S9multifile5ClassCfD
$S9multifile5ClassCfd
$S9multifile6Class2C10staticFunc8default_ySi_tFZ
$S9multifile6Class2C8propertySivg
$S9multifile6Class2C8propertySivgTj
$S9multifile6Class2C8propertySivm
$S9multifile6Class2C8propertySivmTj
$S9multifile6Class2C8propertySivs
$S9multifile6Class2C8propertySivsTj
$S9multifile6Class2CACycfC
$S9multifile6Class2CACycfc
$S9multifile6Class2CACycfcTj
$S9multifile6Class2CMa
$S9multifile6Class2CMm
$S9multifile6Class2CMn
$S9multifile6Class2CMo
$S9multifile6Class2CN
$S9multifile6Class2CfD
$S9multifile6Class2Cfd
$S9multifile8functionyyF
$S9multifile9function2yyF
11 changes: 11 additions & 0 deletions test/TBD/Inputs/multi-file2.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
public func function2() {}

public class Class2 {
public var property: Int

public init() {
property = 0
}

public static func staticFunc(default_: Int = 0) {}
}
55 changes: 55 additions & 0 deletions test/TBD/multi-file.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// RUN: %empty-directory(%t)

// -Onone, non-resilient

// RUN: %target-build-swift -swift-version 4 -module-name multifile -emit-library -o %t/JustForTBDValidation %s %S/Inputs/multi-file2.swift -wmo -Xfrontend -validate-tbd-against-ir=all
// RUN: %target-build-swift -swift-version 4 -module-name multifile -emit-library -o %t/JustForTBDValidation %s %S/Inputs/multi-file2.swift -Xfrontend -validate-tbd-against-ir=all

// RUN: %target-build-swift -swift-version 4 -module-name multifile -emit-tbd-path %t/TBD.tbd -emit-module-path %t/multifile.swiftmodule %s %S/Inputs/multi-file2.swift -wmo
// RUN: diff %t/TBD.tbd %S/Inputs/multi-file-nonresilient-expected.tbd
// RUN: %target-build-swift -swift-version 4 -module-name multifile -emit-tbd-path %t/TBD.tbd -emit-module-path %t/multifile.swiftmodule %s %S/Inputs/multi-file2.swift
// RUN: diff %t/TBD.tbd %S/Inputs/multi-file-nonresilient-expected.tbd

// -O, non-resilient

// RUN: %target-build-swift -swift-version 4 -module-name multifile -emit-library -o %t/JustForTBDValidation %s %S/Inputs/multi-file2.swift -wmo -O -Xfrontend -validate-tbd-against-ir=all
// RUN: %target-build-swift -swift-version 4 -module-name multifile -emit-library -o %t/JustForTBDValidation %s %S/Inputs/multi-file2.swift -O -Xfrontend -validate-tbd-against-ir=all

// RUN: %target-build-swift -swift-version 4 -module-name multifile -emit-tbd-path %t/TBD.tbd -emit-module-path %t/multifile.swiftmodule %s %S/Inputs/multi-file2.swift -wmo -O
// RUN: diff %t/TBD.tbd %S/Inputs/multi-file-nonresilient-expected.tbd
// RUN: %target-build-swift -swift-version 4 -module-name multifile -emit-tbd-path %t/TBD.tbd -emit-module-path %t/multifile.swiftmodule %s %S/Inputs/multi-file2.swift -O
// RUN: diff %t/TBD.tbd %S/Inputs/multi-file-nonresilient-expected.tbd

// -Onone, resilient

// RUN: %target-build-swift -swift-version 4 -module-name multifile -emit-library -o %t/JustForTBDValidation %s %S/Inputs/multi-file2.swift -wmo -Xfrontend -enable-resilience -Xfrontend -validate-tbd-against-ir=all
// RUN: %target-build-swift -swift-version 4 -module-name multifile -emit-library -o %t/JustForTBDValidation %s %S/Inputs/multi-file2.swift -Xfrontend -enable-resilience -Xfrontend -validate-tbd-against-ir=all

// RUN: %target-build-swift -swift-version 4 -module-name multifile -emit-tbd-path %t/TBD.tbd -emit-module-path %t/multifile.swiftmodule %s %S/Inputs/multi-file2.swift -wmo -Xfrontend -enable-resilience
// RUN: diff %t/TBD.tbd %S/Inputs/multi-file-resilient-expected.tbd
// RUN: %target-build-swift -swift-version 4 -module-name multifile -emit-tbd-path %t/TBD.tbd -emit-module-path %t/multifile.swiftmodule %s %S/Inputs/multi-file2.swift -Xfrontend -enable-resilience
// RUN: diff %t/TBD.tbd %S/Inputs/multi-file-resilient-expected.tbd

// -O, resilient

// RUN: %target-build-swift -swift-version 4 -module-name multifile -emit-library -o %t/JustForTBDValidation %s %S/Inputs/multi-file2.swift -wmo -O -Xfrontend -enable-resilience -Xfrontend -validate-tbd-against-ir=all
// RUN: %target-build-swift -swift-version 4 -module-name multifile -emit-library -o %t/JustForTBDValidation %s %S/Inputs/multi-file2.swift -O -Xfrontend -enable-resilience -Xfrontend -validate-tbd-against-ir=all

// RUN: %target-build-swift -swift-version 4 -module-name multifile -emit-tbd-path %t/TBD.tbd -emit-module-path %t/multifile.swiftmodule %s %S/Inputs/multi-file2.swift -wmo -O -Xfrontend -enable-resilience
// RUN: diff %t/TBD.tbd %S/Inputs/multi-file-resilient-expected.tbd
// RUN: %target-build-swift -swift-version 4 -module-name multifile -emit-tbd-path %t/TBD.tbd -emit-module-path %t/multifile.swiftmodule %s %S/Inputs/multi-file2.swift -O -Xfrontend -enable-resilience
// RUN: diff %t/TBD.tbd %S/Inputs/multi-file-resilient-expected.tbd

// REQUIRES: objc_interop

public func function() {}

public class Class {
public var property: Int

public init() {
property = 0
}

public static func staticFunc(default_: Int = 0) {}
}
12 changes: 12 additions & 0 deletions test/TBD/output-path-deduction.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// RUN: %empty-directory(%t)

// RUN: cd %t; %target-build-swift -emit-module -emit-tbd %s
// RUN: test -e %t/main.tbd
// RUN: %target-build-swift -emit-module -emit-tbd %s -o %t/default
// RUN: test -e %t/default.tbd
// RUN: %target-build-swift -emit-module -emit-tbd %s -o %t/module_name -module-name module_name_different
// RUN: test -e %t/module_name.tbd
// RUN: %target-build-swift -emit-module -emit-tbd-path %t/hard_to_guess_explicit_path.tbd %s -o %t/explicit_path
// RUN: test -e %t/hard_to_guess_explicit_path.tbd
// RUN: %target-build-swift -emit-module -emit-tbd %s -emit-module-path %t/emit_module_path.swiftmodule -module-name emit_module_path_different
// RUN: test -e %t/emit_module_path.tbd