Revert "Revert "Merge pull request #41831 from hyp/unify-header""

This reverts commit 4c9582c295.
This commit is contained in:
Alex Lorenz
2022-03-19 13:36:28 -07:00
parent 36b41d4940
commit 2e3aa87737
29 changed files with 163 additions and 226 deletions

View File

@@ -118,9 +118,7 @@ ERROR(error_mode_cannot_emit_dependencies,none,
ERROR(error_mode_cannot_emit_reference_dependencies,none,
"this mode does not support emitting reference dependency files", ())
ERROR(error_mode_cannot_emit_header,none,
"this mode does not support emitting Objective-C headers", ())
ERROR(error_mode_cannot_emit_cxx_header,none,
"this mode does not support emitting C++ headers", ())
"this mode does not support emitting Objective-C or C++ headers", ())
ERROR(error_mode_cannot_emit_loaded_module_trace,none,
"this mode does not support emitting the loaded module trace", ())
ERROR(error_mode_cannot_emit_module,none,

View File

@@ -59,8 +59,7 @@ TYPE("raw-sib", RawSIB, "sib", "")
TYPE("llvm-ir", LLVM_IR, "ll", "")
TYPE("llvm-bc", LLVM_BC, "bc", "")
TYPE("diagnostics", SerializedDiagnostics, "dia", "")
TYPE("objc-header", ObjCHeader, "h", "")
TYPE("cxx-header", CXXHeader, "h", "")
TYPE("clang-header", ClangHeader, "h", "")
TYPE("swift-dependencies", SwiftDeps, "swiftdeps", "")
TYPE("external-swift-dependencies", ExternalSwiftDeps, "swiftdeps.external", "")
TYPE("remap", Remapping, "remap", "")

View File

@@ -20,7 +20,8 @@
namespace swift {
struct SupplementaryOutputPaths {
/// The path to which we should emit an Objective-C header for the module.
/// The path to which we should emit a header file that exposes the Swift
/// declarations to C, Objective-C and C++ clients for the module.
///
/// Currently only makes sense when the compiler has whole module knowledge.
/// The modes for which it makes sense incuide both WMO and the "merge
@@ -28,19 +29,8 @@ struct SupplementaryOutputPaths {
/// the header is emitted in single-file mode, since it needs whole-module
/// information.
///
/// \sa swift::printAsObjC
std::string ObjCHeaderOutputPath;
/// The path to which we should emit a C++ header for the module.
///
/// Currently only makes sense when the compiler has whole module knowledge.
/// The modes for which it makes sense include both WMO and the "merge
/// modules" job that happens after the normal compilation jobs. That's where
/// the header is emitted in single-file mode, since it needs whole-module
/// information.
///
/// \sa swift::printAsCXX
std::string CxxHeaderOutputPath;
/// \sa swift::printAsClangHeader
std::string ClangHeaderOutputPath;
/// The path to which we should emit a serialized module.
/// It is valid whenever there are any inputs.
@@ -170,10 +160,8 @@ struct SupplementaryOutputPaths {
/// Apply a given function for each existing (non-empty string) supplementary output
void forEachSetOutput(llvm::function_ref<void(const std::string&)> fn) const {
if (!ObjCHeaderOutputPath.empty())
fn(ObjCHeaderOutputPath);
if (!CxxHeaderOutputPath.empty())
fn(CxxHeaderOutputPath);
if (!ClangHeaderOutputPath.empty())
fn(ClangHeaderOutputPath);
if (!ModuleOutputPath.empty())
fn(ModuleOutputPath);
if (!ModuleSourceInfoOutputPath.empty())
@@ -209,9 +197,8 @@ struct SupplementaryOutputPaths {
}
bool empty() const {
return ObjCHeaderOutputPath.empty() && CxxHeaderOutputPath.empty() &&
ModuleOutputPath.empty() && ModuleDocOutputPath.empty() &&
DependenciesFilePath.empty() &&
return ClangHeaderOutputPath.empty() && ModuleOutputPath.empty() &&
ModuleDocOutputPath.empty() && DependenciesFilePath.empty() &&
ReferenceDependenciesFilePath.empty() &&
SerializedDiagnosticsPath.empty() && LoadedModuleTracePath.empty() &&
TBDPath.empty() && ModuleInterfaceOutputPath.empty() &&

View File

@@ -392,8 +392,7 @@ public:
std::string getOutputFilenameForAtMostOnePrimary() const;
std::string getMainInputFilenameForDebugInfoForAtMostOnePrimary() const;
std::string getObjCHeaderOutputPathForAtMostOnePrimary() const;
std::string getCxxHeaderOutputPathForAtMostOnePrimary() const;
std::string getClangHeaderOutputPathForAtMostOnePrimary() const;
std::string getModuleOutputPathForAtMostOnePrimary() const;
std::string
getReferenceDependenciesFilePathForPrimary(StringRef filename) const;

View File

@@ -249,8 +249,7 @@ public:
bool hasDependenciesPath() const;
bool hasReferenceDependenciesPath() const;
bool hasObjCHeaderOutputPath() const;
bool hasCxxHeaderOutputPath() const;
bool hasClangHeaderOutputPath() const;
bool hasLoadedModuleTracePath() const;
bool hasModuleOutputPath() const;
bool hasModuleDocOutputPath() const;

View File

@@ -532,13 +532,11 @@ def emit_objc_header_path : Separate<["-"], "emit-objc-header-path">,
SupplementaryOutput]>,
MetaVarName<"<path>">, HelpText<"Emit an Objective-C header file to <path>">;
def emit_cxx_header : Flag<["-"], "emit-cxx-header">,
Flags<[FrontendOption, NoInteractiveOption, SupplementaryOutput]>,
HelpText<"Emit a C++ header file">;
def emit_cxx_header_path : Separate<["-"], "emit-cxx-header-path">,
Flags<[FrontendOption, NoInteractiveOption, ArgumentIsPath,
def emit_clang_header_path : Separate<["-"], "emit-clang-header-path">,
Flags<[FrontendOption, NoDriverOption, NoInteractiveOption, ArgumentIsPath,
SupplementaryOutput]>,
MetaVarName<"<path>">, HelpText<"Emit a C++ header file to <path>">;
HelpText<"Emit an Objective-C and C++ header file to <path>">,
Alias<emit_objc_header_path>;
def static : Flag<["-"], "static">,
Flags<[FrontendOption, ModuleInterfaceOption, NoInteractiveOption]>,

View File

@@ -21,16 +21,18 @@ namespace swift {
class ModuleDecl;
class ValueDecl;
/// Print the Objective-C-compatible declarations in a module as a Clang
/// header.
/// Print the exposed declarations in a module into a Clang header.
///
/// The Objective-C compatible declarations are printed into a block that
/// ensures that those declarations are only usable when the header is
/// compiled in Objective-C mode.
/// The C++ compatible declarations are printed into a block that ensures
/// that those declarations are only usable when the header is compiled in
/// C++ mode.
///
/// Returns true on error.
bool printAsObjC(raw_ostream &out, ModuleDecl *M, StringRef bridgingHeader);
/// Print the C++-compatible declarations in a module as a Clang header.
///
/// Returns true on error.
bool printAsCXX(raw_ostream &os, ModuleDecl *M);
bool printAsClangHeader(raw_ostream &out, ModuleDecl *M,
StringRef bridgingHeader);
}
#endif

View File

@@ -73,8 +73,7 @@ bool file_types::isTextual(ID Id) {
case file_types::TY_ASTDump:
case file_types::TY_RawSIL:
case file_types::TY_LLVM_IR:
case file_types::TY_ObjCHeader:
case file_types::TY_CXXHeader:
case file_types::TY_ClangHeader:
case file_types::TY_AutolinkFile:
case file_types::TY_ImportedModules:
case file_types::TY_TBD:
@@ -132,8 +131,7 @@ bool file_types::isAfterLLVM(ID Id) {
case file_types::TY_Dependencies:
case file_types::TY_ASTDump:
case file_types::TY_RawSIL:
case file_types::TY_ObjCHeader:
case file_types::TY_CXXHeader:
case file_types::TY_ClangHeader:
case file_types::TY_AutolinkFile:
case file_types::TY_Image:
case file_types::TY_dSYM:
@@ -183,8 +181,7 @@ bool file_types::isPartOfSwiftCompilation(ID Id) {
case file_types::TY_LLVM_BC:
case file_types::TY_Object:
case file_types::TY_Dependencies:
case file_types::TY_ObjCHeader:
case file_types::TY_CXXHeader:
case file_types::TY_ClangHeader:
case file_types::TY_AutolinkFile:
case file_types::TY_PCH:
case file_types::TY_ImportedModules:

View File

@@ -1981,8 +1981,7 @@ void Driver::buildActions(SmallVectorImpl<const Action *> &TopLevelActions,
if (Arg *A = Args.getLastArg(options::OPT_import_objc_header)) {
StringRef Value = A->getValue();
auto Ty = TC.lookupTypeForExtension(llvm::sys::path::extension(Value));
if (Ty == file_types::TY_ObjCHeader ||
Ty == file_types::TY_CXXHeader) {
if (Ty == file_types::TY_ClangHeader) {
auto *HeaderInput = C.createAction<InputAction>(*A, Ty);
StringRef PersistentPCHDir;
if (const Arg *A = Args.getLastArg(options::OPT_pch_output_dir)) {
@@ -2065,8 +2064,7 @@ void Driver::buildActions(SmallVectorImpl<const Action *> &TopLevelActions,
case file_types::TY_LLVM_IR:
case file_types::TY_LLVM_BC:
case file_types::TY_SerializedDiagnostics:
case file_types::TY_ObjCHeader:
case file_types::TY_CXXHeader:
case file_types::TY_ClangHeader:
case file_types::TY_ClangModuleFile:
case file_types::TY_SwiftDeps:
case file_types::TY_ExternalSwiftDeps:
@@ -3480,12 +3478,12 @@ void Driver::chooseObjectiveCHeaderOutputPath(Compilation &C,
StringRef workingDirectory,
CommandOutput *Output) const {
if (hasExistingAdditionalOutput(*Output, file_types::TY_ObjCHeader))
if (hasExistingAdditionalOutput(*Output, file_types::TY_ClangHeader))
return;
StringRef ObjCHeaderPath;
if (OutputMap) {
auto iter = OutputMap->find(file_types::TY_ObjCHeader);
auto iter = OutputMap->find(file_types::TY_ClangHeader);
if (iter != OutputMap->end())
ObjCHeaderPath = iter->second;
}
@@ -3495,13 +3493,13 @@ void Driver::chooseObjectiveCHeaderOutputPath(Compilation &C,
ObjCHeaderPath = A->getValue();
if (!ObjCHeaderPath.empty()) {
Output->setAdditionalOutputForType(file_types::TY_ObjCHeader,
Output->setAdditionalOutputForType(file_types::TY_ClangHeader,
ObjCHeaderPath);
} else {
// Put the header next to the primary output file.
// FIXME: That's not correct if the user /just/ passed -emit-header
// and not -emit-module.
addAuxiliaryOutput(C, *Output, file_types::TY_ObjCHeader,
addAuxiliaryOutput(C, *Output, file_types::TY_ClangHeader,
/*output file map*/ nullptr, workingDirectory);
}
}

View File

@@ -675,8 +675,7 @@ const char *ToolChain::JobContext::computeFrontendModeForCompile() const {
case file_types::TY_Dependencies:
case file_types::TY_SwiftModuleDocFile:
case file_types::TY_SerializedDiagnostics:
case file_types::TY_ObjCHeader:
case file_types::TY_CXXHeader:
case file_types::TY_ClangHeader:
case file_types::TY_Image:
case file_types::TY_SwiftDeps:
case file_types::TY_ExternalSwiftDeps:
@@ -815,7 +814,7 @@ void ToolChain::JobContext::addFrontendSupplementaryOutputArguments(
file_types::TY_SerializedDiagnostics,
"-serialize-diagnostics-path");
if (addOutputsOfType(arguments, Output, Args, file_types::ID::TY_ObjCHeader,
if (addOutputsOfType(arguments, Output, Args, file_types::ID::TY_ClangHeader,
"-emit-objc-header-path")) {
assert(OI.CompilerMode == OutputInfo::Mode::SingleCompile &&
"The Swift tool should only emit an Obj-C header in single compile"
@@ -936,8 +935,7 @@ ToolChain::constructInvocation(const BackendJobAction &job,
case file_types::TY_Dependencies:
case file_types::TY_SwiftModuleDocFile:
case file_types::TY_SerializedDiagnostics:
case file_types::TY_ObjCHeader:
case file_types::TY_CXXHeader:
case file_types::TY_ClangHeader:
case file_types::TY_Image:
case file_types::TY_SwiftDeps:
case file_types::TY_ExternalSwiftDeps:
@@ -1100,7 +1098,7 @@ ToolChain::constructInvocation(const MergeModuleJobAction &job,
file_types::TY_SerializedDiagnostics,
"-serialize-diagnostics-path");
addOutputsOfType(Arguments, context.Output, context.Args,
file_types::TY_ObjCHeader, "-emit-objc-header-path");
file_types::TY_ClangHeader, "-emit-objc-header-path");
addOutputsOfType(Arguments, context.Output, context.Args, file_types::TY_TBD,
"-emit-tbd-path");
@@ -1309,7 +1307,7 @@ ToolChain::constructInvocation(const GeneratePCHJobAction &job,
file_types::TY_SerializedDiagnostics,
"-serialize-diagnostics-path");
addInputsOfType(Arguments, context.InputActions, file_types::TY_ObjCHeader);
addInputsOfType(Arguments, context.InputActions, file_types::TY_ClangHeader);
context.Args.AddLastArg(Arguments, options::OPT_index_store_path);
if (job.isPersistentPCH()) {

View File

@@ -625,15 +625,10 @@ bool ArgsToFrontendOptionsConverter::checkUnusedSupplementaryOutputPaths()
return true;
}
if (!FrontendOptions::canActionEmitClangHeader(Opts.RequestedAction) &&
Opts.InputsAndOutputs.hasObjCHeaderOutputPath()) {
Opts.InputsAndOutputs.hasClangHeaderOutputPath()) {
Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_header);
return true;
}
if (!FrontendOptions::canActionEmitClangHeader(Opts.RequestedAction) &&
Opts.InputsAndOutputs.hasCxxHeaderOutputPath()) {
Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_cxx_header);
return true;
}
if (!FrontendOptions::canActionEmitLoadedModuleTrace(Opts.RequestedAction) &&
Opts.InputsAndOutputs.hasLoadedModuleTracePath()) {
Diags.diagnose(SourceLoc(),

View File

@@ -308,10 +308,8 @@ Optional<std::vector<SupplementaryOutputPaths>>
SupplementaryOutputPathsComputer::getSupplementaryOutputPathsFromArguments()
const {
auto objCHeaderOutput = getSupplementaryFilenamesFromArguments(
auto clangHeaderOutput = getSupplementaryFilenamesFromArguments(
options::OPT_emit_objc_header_path);
auto cxxHeaderOutput =
getSupplementaryFilenamesFromArguments(options::OPT_emit_cxx_header_path);
auto moduleOutput =
getSupplementaryFilenamesFromArguments(options::OPT_emit_module_path);
auto moduleDocOutput =
@@ -341,8 +339,8 @@ SupplementaryOutputPathsComputer::getSupplementaryOutputPathsFromArguments()
options::OPT_emit_module_semantic_info_path);
auto optRecordOutput = getSupplementaryFilenamesFromArguments(
options::OPT_save_optimization_record_path);
if (!objCHeaderOutput || !cxxHeaderOutput || !moduleOutput ||
!moduleDocOutput || !dependenciesFile || !referenceDependenciesFile ||
if (!clangHeaderOutput || !moduleOutput || !moduleDocOutput ||
!dependenciesFile || !referenceDependenciesFile ||
!serializedDiagnostics || !fixItsOutput || !loadedModuleTrace || !TBD ||
!moduleInterfaceOutput || !privateModuleInterfaceOutput ||
!moduleSourceInfoOutput || !moduleSummaryOutput || !abiDescriptorOutput ||
@@ -355,8 +353,7 @@ SupplementaryOutputPathsComputer::getSupplementaryOutputPathsFromArguments()
InputsAndOutputs.countOfFilesProducingSupplementaryOutput();
for (unsigned i = 0; i < N; ++i) {
SupplementaryOutputPaths sop;
sop.ObjCHeaderOutputPath = (*objCHeaderOutput)[i];
sop.CxxHeaderOutputPath = (*cxxHeaderOutput)[i];
sop.ClangHeaderOutputPath = (*clangHeaderOutput)[i];
sop.ModuleOutputPath = (*moduleOutput)[i];
sop.ModuleDocOutputPath = (*moduleDocOutput)[i];
sop.DependenciesFilePath = (*dependenciesFile)[i];
@@ -437,14 +434,9 @@ SupplementaryOutputPathsComputer::computeOutputPathsForOneInput(
// There is no non-path form of -emit-fixits-path
auto fixItsOutputPath = pathsFromArguments.FixItsOutputPath;
auto objcHeaderOutputPath = determineSupplementaryOutputFilename(
OPT_emit_objc_header, pathsFromArguments.ObjCHeaderOutputPath,
file_types::TY_ObjCHeader, "",
defaultSupplementaryOutputPathExcludingExtension);
auto cxxHeaderOutputPath = determineSupplementaryOutputFilename(
OPT_emit_cxx_header, pathsFromArguments.CxxHeaderOutputPath,
file_types::TY_CXXHeader, "",
auto clangHeaderOutputPath = determineSupplementaryOutputFilename(
OPT_emit_objc_header, pathsFromArguments.ClangHeaderOutputPath,
file_types::TY_ClangHeader, "",
defaultSupplementaryOutputPathExcludingExtension);
auto loadedModuleTracePath = determineSupplementaryOutputFilename(
@@ -500,8 +492,7 @@ SupplementaryOutputPathsComputer::computeOutputPathsForOneInput(
defaultSupplementaryOutputPathExcludingExtension);
SupplementaryOutputPaths sop;
sop.ObjCHeaderOutputPath = objcHeaderOutputPath;
sop.CxxHeaderOutputPath = cxxHeaderOutputPath;
sop.ClangHeaderOutputPath = clangHeaderOutputPath;
sop.ModuleOutputPath = moduleOutputPath;
sop.ModuleDocOutputPath = moduleDocOutputPath;
sop.DependenciesFilePath = dependenciesFilePath;
@@ -586,8 +577,7 @@ createFromTypeToPathMap(const TypeToPathMap *map) {
if (!map)
return paths;
const std::pair<file_types::ID, std::string &> typesAndStrings[] = {
{file_types::TY_ObjCHeader, paths.ObjCHeaderOutputPath},
{file_types::TY_CXXHeader, paths.CxxHeaderOutputPath},
{file_types::TY_ClangHeader, paths.ClangHeaderOutputPath},
{file_types::TY_SwiftModuleFile, paths.ModuleOutputPath},
{file_types::TY_SwiftModuleDocFile, paths.ModuleDocOutputPath},
{file_types::TY_SwiftSourceInfoFile, paths.ModuleSourceInfoOutputPath},
@@ -615,17 +605,17 @@ createFromTypeToPathMap(const TypeToPathMap *map) {
Optional<std::vector<SupplementaryOutputPaths>>
SupplementaryOutputPathsComputer::readSupplementaryOutputFileMap() const {
if (Arg *A = Args.getLastArg(
options::OPT_emit_objc_header_path, options::OPT_emit_cxx_header_path,
options::OPT_emit_module_path, options::OPT_emit_module_doc_path,
options::OPT_emit_dependencies_path,
options::OPT_emit_reference_dependencies_path,
options::OPT_serialize_diagnostics_path,
options::OPT_emit_loaded_module_trace_path,
options::OPT_emit_module_interface_path,
options::OPT_emit_private_module_interface_path,
options::OPT_emit_module_source_info_path,
options::OPT_emit_tbd_path)) {
if (Arg *A = Args.getLastArg(options::OPT_emit_objc_header_path,
options::OPT_emit_module_path,
options::OPT_emit_module_doc_path,
options::OPT_emit_dependencies_path,
options::OPT_emit_reference_dependencies_path,
options::OPT_serialize_diagnostics_path,
options::OPT_emit_loaded_module_trace_path,
options::OPT_emit_module_interface_path,
options::OPT_emit_private_module_interface_path,
options::OPT_emit_module_source_info_path,
options::OPT_emit_tbd_path)) {
Diags.diagnose(SourceLoc(),
diag::error_cannot_have_supplementary_outputs,
A->getSpelling(), "-supplementary-output-file-map");

View File

@@ -92,14 +92,9 @@ CompilerInvocation::getMainInputFilenameForDebugInfoForAtMostOnePrimary()
.MainInputFilenameForDebugInfo;
}
std::string
CompilerInvocation::getObjCHeaderOutputPathForAtMostOnePrimary() const {
CompilerInvocation::getClangHeaderOutputPathForAtMostOnePrimary() const {
return getPrimarySpecificPathsForAtMostOnePrimary()
.SupplementaryOutputs.ObjCHeaderOutputPath;
}
std::string
CompilerInvocation::getCxxHeaderOutputPathForAtMostOnePrimary() const {
return getPrimarySpecificPathsForAtMostOnePrimary()
.SupplementaryOutputs.CxxHeaderOutputPath;
.SupplementaryOutputs.ClangHeaderOutputPath;
}
std::string CompilerInvocation::getModuleOutputPathForAtMostOnePrimary() const {
return getPrimarySpecificPathsForAtMostOnePrimary()

View File

@@ -213,7 +213,7 @@ bool FrontendInputsAndOutputs::shouldTreatAsObjCHeader() const {
if (hasSingleInput()) {
StringRef InputExt = llvm::sys::path::extension(getFilenameOfFirstInput());
switch (file_types::lookupTypeForExtension(InputExt)) {
case file_types::TY_ObjCHeader:
case file_types::TY_ClangHeader:
return true;
default:
return false;
@@ -461,16 +461,10 @@ bool FrontendInputsAndOutputs::hasReferenceDependenciesPath() const {
return outs.ReferenceDependenciesFilePath;
});
}
bool FrontendInputsAndOutputs::hasObjCHeaderOutputPath() const {
bool FrontendInputsAndOutputs::hasClangHeaderOutputPath() const {
return hasSupplementaryOutputPath(
[](const SupplementaryOutputPaths &outs) -> const std::string & {
return outs.ObjCHeaderOutputPath;
});
}
bool FrontendInputsAndOutputs::hasCxxHeaderOutputPath() const {
return hasSupplementaryOutputPath(
[](const SupplementaryOutputPaths &outs) -> const std::string & {
return outs.CxxHeaderOutputPath;
return outs.ClangHeaderOutputPath;
});
}
bool FrontendInputsAndOutputs::hasLoadedModuleTracePath() const {

View File

@@ -234,8 +234,7 @@ void FrontendOptions::forAllOutputPaths(
const std::string *outputs[] = {
&outs.ModuleOutputPath, &outs.ModuleDocOutputPath,
&outs.ModuleInterfaceOutputPath, &outs.PrivateModuleInterfaceOutputPath,
&outs.ObjCHeaderOutputPath, &outs.CxxHeaderOutputPath,
&outs.ModuleSourceInfoOutputPath};
&outs.ClangHeaderOutputPath, &outs.ModuleSourceInfoOutputPath};
for (const std::string *next : outputs) {
if (!next->empty())
fn(*next);

View File

@@ -170,36 +170,22 @@ static bool writeSIL(SILModule &SM, const PrimarySpecificPaths &PSPs,
/// Prints the Objective-C "generated header" interface for \p M to \p
/// outputPath.
///
/// ...unless \p outputPath is empty, in which case it does nothing.
///
/// \returns true if there were any errors
///
/// \see swift::printAsObjC
static bool printAsObjCIfNeeded(StringRef outputPath, ModuleDecl *M,
StringRef bridgingHeader) {
if (outputPath.empty())
return false;
return withOutputFile(M->getDiags(), outputPath,
[&](raw_ostream &out) -> bool {
return printAsObjC(out, M, bridgingHeader);
});
}
/// Prints the C++ "generated header" interface for \p M to \p
/// Print the exposed "generated header" interface for \p M to \p
/// outputPath.
///
/// ...unless \p outputPath is empty, in which case it does nothing.
///
/// \returns true if there were any errors
///
/// \see swift::printAsCXX
static bool printAsCxxIfNeeded(StringRef outputPath, ModuleDecl *M) {
/// \see swift::printAsClangHeader
static bool printAsClangHeaderIfNeeded(StringRef outputPath, ModuleDecl *M,
StringRef bridgingHeader) {
if (outputPath.empty())
return false;
return withOutputFile(
M->getDiags(), outputPath,
[&](raw_ostream &os) -> bool { return printAsCXX(os, M); });
return withOutputFile(M->getDiags(), outputPath,
[&](raw_ostream &out) -> bool {
return printAsClangHeader(out, M, bridgingHeader);
});
}
/// Prints the stable module interface for \p M to \p outputPath.
@@ -824,7 +810,7 @@ static bool emitAnyWholeModulePostTypeCheckSupplementaryOutputs(
bool hadAnyError = false;
if ((!Context.hadError() || opts.AllowModuleWithCompilerErrors) &&
opts.InputsAndOutputs.hasObjCHeaderOutputPath()) {
opts.InputsAndOutputs.hasClangHeaderOutputPath()) {
std::string BridgingHeaderPathForPrint;
if (!opts.ImplicitObjCHeaderPath.empty()) {
if (opts.BridgingHeaderDirForPrint.hasValue()) {
@@ -838,16 +824,10 @@ static bool emitAnyWholeModulePostTypeCheckSupplementaryOutputs(
BridgingHeaderPathForPrint = opts.ImplicitObjCHeaderPath;
}
}
hadAnyError |= printAsObjCIfNeeded(
Invocation.getObjCHeaderOutputPathForAtMostOnePrimary(),
hadAnyError |= printAsClangHeaderIfNeeded(
Invocation.getClangHeaderOutputPathForAtMostOnePrimary(),
Instance.getMainModule(), BridgingHeaderPathForPrint);
}
if ((!Context.hadError() || opts.AllowModuleWithCompilerErrors) &&
opts.InputsAndOutputs.hasCxxHeaderOutputPath()) {
hadAnyError |= printAsCxxIfNeeded(
Invocation.getCxxHeaderOutputPathForAtMostOnePrimary(),
Instance.getMainModule());
}
// Only want the header if there's been any errors, ie. there's not much
// point outputting a swiftinterface for an invalid module

View File

@@ -26,28 +26,32 @@
using namespace swift;
static void emitCxxConditional(raw_ostream &out,
llvm::function_ref<void()> cxxCase,
llvm::function_ref<void()> cCase = {}) {
out << "#if defined(__cplusplus)\n";
cxxCase();
if (cCase) {
out << "#else\n";
cCase();
}
out << "#endif\n";
}
static void emitObjCConditional(raw_ostream &out,
llvm::function_ref<void()> objcCase,
llvm::function_ref<void()> nonObjCCase = {}) {
out << "#if defined(__OBJC__)\n";
objcCase();
if (nonObjCCase) {
out << "#else\n";
nonObjCCase();
}
out << "#endif\n";
}
static void writePrologue(raw_ostream &out, ASTContext &ctx,
StringRef macroGuard) {
auto emitCxxConditional = [&](llvm::function_ref<void()> cxxCase,
llvm::function_ref<void()> cCase = {}) {
out << "#if defined(__cplusplus)\n";
cxxCase();
if (cCase) {
out << "#else\n";
cCase();
}
out << "#endif\n";
};
auto emitObjCConditional = [&](llvm::function_ref<void()> objcCase,
llvm::function_ref<void()> nonObjCCase = {}) {
out << "#if defined(__OBJC__)\n";
objcCase();
if (nonObjCCase) {
out << "#else\n";
nonObjCCase();
}
out << "#endif\n";
};
out << "// Generated by "
<< version::getSwiftFullVersion(ctx.LangOpts.EffectiveLanguageVersion)
@@ -77,8 +81,10 @@ static void writePrologue(raw_ostream &out, ASTContext &ctx,
"#endif\n"
"\n"
"#pragma clang diagnostic ignored \"-Wauto-import\"\n";
emitObjCConditional([&] { out << "#include <Foundation/Foundation.h>\n"; });
emitObjCConditional(out,
[&] { out << "#include <Foundation/Foundation.h>\n"; });
emitCxxConditional(
out,
[&] {
out << "#include <cstdint>\n"
"#include <cstddef>\n"
@@ -276,7 +282,7 @@ static void writePrologue(raw_ostream &out, ASTContext &ctx,
"#else\n"
"# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg)\n"
"#endif\n";
emitObjCConditional([&] {
emitObjCConditional(out, [&] {
out << "#if !defined(IBSegueAction)\n"
"# define IBSegueAction\n"
"#endif\n";
@@ -295,8 +301,9 @@ static void writePrologue(raw_ostream &out, ASTContext &ctx,
};
emitMacro("SWIFT_CALL", "__attribute__((swiftcall))");
// SWIFT_NOEXCEPT applies 'noexcept' in C++ mode only.
emitCxxConditional([&] { emitMacro("SWIFT_NOEXCEPT", "noexcept"); },
[&] { emitMacro("SWIFT_NOEXCEPT"); });
emitCxxConditional(
out, [&] { emitMacro("SWIFT_NOEXCEPT", "noexcept"); },
[&] { emitMacro("SWIFT_NOEXCEPT"); });
static_assert(SWIFT_MAX_IMPORTED_SIMD_ELEMENTS == 4,
"need to add SIMD typedefs here if max elements is increased");
}
@@ -442,33 +449,33 @@ static std::string computeMacroGuard(const ModuleDecl *M) {
return (llvm::Twine(M->getNameStr().upper()) + "_SWIFT_H").str();
}
bool swift::printAsObjC(raw_ostream &os, ModuleDecl *M,
StringRef bridgingHeader) {
llvm::PrettyStackTraceString trace("While generating Objective-C header");
static std::string getModuleContentsCxxString(ModuleDecl &M) {
SmallPtrSet<ImportModuleTy, 8> imports;
std::string moduleContentsBuf;
llvm::raw_string_ostream moduleContents{moduleContentsBuf};
printModuleContentsAsObjC(moduleContents, imports, *M);
printModuleContentsAsCxx(moduleContents, imports, M);
return moduleContents.str();
}
bool swift::printAsClangHeader(raw_ostream &os, ModuleDecl *M,
StringRef bridgingHeader) {
llvm::PrettyStackTraceString trace("While generating Clang header");
SmallPtrSet<ImportModuleTy, 8> imports;
std::string objcModuleContentsBuf;
llvm::raw_string_ostream objcModuleContents{objcModuleContentsBuf};
printModuleContentsAsObjC(objcModuleContents, imports, *M);
writePrologue(os, M->getASTContext(), computeMacroGuard(M));
writeImports(os, imports, *M, bridgingHeader);
emitObjCConditional(os,
[&] { writeImports(os, imports, *M, bridgingHeader); });
writePostImportPrologue(os, *M);
os << moduleContents.str();
writeEpilogue(os);
return false;
}
bool swift::printAsCXX(raw_ostream &os, ModuleDecl *M) {
llvm::PrettyStackTraceString trace("While generating C++ header");
SmallPtrSet<ImportModuleTy, 8> imports;
std::string moduleContentsBuf;
llvm::raw_string_ostream moduleContents{moduleContentsBuf};
printModuleContentsAsCxx(moduleContents, imports, *M);
writePrologue(os, M->getASTContext(), computeMacroGuard(M));
writePostImportPrologue(os, *M);
os << moduleContents.str();
emitObjCConditional(os, [&] { os << objcModuleContents.str(); });
emitCxxConditional(os, [&] {
// FIXME: Expose Swift with @expose by default.
if (M->getASTContext().LangOpts.EnableCXXInterop) {
os << getModuleContentsCxxString(*M);
}
});
writeEpilogue(os);
return false;

View File

@@ -1,7 +1,7 @@
// RUN: %empty-directory(%t)
// RUN: %target-build-swift -typecheck -driver-print-actions -import-objc-header %S/Inputs/bridging-header.h %s 2>&1 | %FileCheck %s -check-prefix=YESPCHACT
// YESPCHACT: 0: input, "{{.*}}Inputs/bridging-header.h", objc-header
// YESPCHACT: 0: input, "{{.*}}Inputs/bridging-header.h", clang-header
// YESPCHACT: 1: generate-pch, {0}, pch
// YESPCHACT: 2: input, "{{.*}}bridging-pch.swift", swift
// YESPCHACT: 3: compile, {2, 1}, none
@@ -30,13 +30,13 @@
// Test persistent PCH
// RUN: %target-build-swift -typecheck -driver-print-actions -import-objc-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch %s 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-YESPCHACT
// PERSISTENT-YESPCHACT: 0: input, "{{.*}}Inputs/bridging-header.h", objc-header
// PERSISTENT-YESPCHACT: 0: input, "{{.*}}Inputs/bridging-header.h", clang-header
// PERSISTENT-YESPCHACT: 1: generate-pch, {0}, none
// PERSISTENT-YESPCHACT: 2: input, "{{.*}}bridging-pch.swift", swift
// PERSISTENT-YESPCHACT: 3: compile, {2, 1}, none
// RUN: %target-build-swift -c -driver-print-actions -embed-bitcode -import-objc-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch %s 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-YESPCHACTBC
// PERSISTENT-YESPCHACTBC: 0: input, "{{.*}}Inputs/bridging-header.h", objc-header
// PERSISTENT-YESPCHACTBC: 0: input, "{{.*}}Inputs/bridging-header.h", clang-header
// PERSISTENT-YESPCHACTBC: 1: generate-pch, {0}, none
// PERSISTENT-YESPCHACTBC: 2: input, "{{.*}}bridging-pch.swift", swift
// PERSISTENT-YESPCHACTBC: 3: compile, {2, 1}, llvm-bc

View File

@@ -94,7 +94,7 @@
// CHECK-NEXT: "path": "{{.*[\\/]}}parseable_output.swift.tmp.swiftsourceinfo"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "type": "objc-header",
// CHECK-NEXT: "type": "clang-header",
// CHECK-NEXT: "path": "{{.*[\\/]}}parseable_output.swift.tmp.h"
// CHECK-NEXT: }
// CHECK-NEXT: ],

View File

@@ -96,7 +96,7 @@
// CHECK-NEXT: "path": "{{.*[\\/]}}parseable_output_unicode.swift.tmp.swiftsourceinfo"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "type": "objc-header",
// CHECK-NEXT: "type": "clang-header",
// CHECK-NEXT: "path": "{{.*[\\/]}}parseable_output_unicode.swift.tmp.h"
// CHECK-NEXT: }
// CHECK-NEXT: ],

View File

@@ -18,18 +18,11 @@
// RESOLVE_IMPORTS_NO_REFERENCE_DEPS: error: this mode does not support emitting reference dependency files{{$}}
// RUN: not %target-swift-frontend -parse -emit-objc-header %s 2>&1 | %FileCheck -check-prefix=PARSE_NO_OBJC_HEADER %s
// PARSE_NO_OBJC_HEADER: error: this mode does not support emitting Objective-C headers{{$}}
// PARSE_NO_OBJC_HEADER: error: this mode does not support emitting Objective-C or C++ headers{{$}}
// RUN: not %target-swift-frontend -dump-ast -emit-objc-header %s 2>&1 | %FileCheck -check-prefix=DUMP_NO_OBJC_HEADER %s
// DUMP_NO_OBJC_HEADER: error: this mode does not support emitting Objective-C headers{{$}}
// DUMP_NO_OBJC_HEADER: error: this mode does not support emitting Objective-C or C++ headers{{$}}
// RUN: not %target-swift-frontend -resolve-imports -emit-objc-header %s 2>&1 | %FileCheck -check-prefix=RESOLVE_IMPORTS_NO_OBJC_HEADER %s
// RESOLVE_IMPORTS_NO_OBJC_HEADER: error: this mode does not support emitting Objective-C headers{{$}}
// RUN: not %target-swift-frontend -parse -emit-cxx-header %s 2>&1 | %FileCheck -check-prefix=PARSE_NO_CXX_HEADER %s
// PARSE_NO_CXX_HEADER: error: this mode does not support emitting C++ headers{{$}}
// RUN: not %target-swift-frontend -dump-ast -emit-cxx-header %s 2>&1 | %FileCheck -check-prefix=DUMP_NO_CXX_HEADER %s
// DUMP_NO_CXX_HEADER: error: this mode does not support emitting C++ headers{{$}}
// RUN: not %target-swift-frontend -resolve-imports -emit-cxx-header %s 2>&1 | %FileCheck -check-prefix=RESOLVE_IMPORTS_NO_CXX_HEADER %s
// RESOLVE_IMPORTS_NO_CXX_HEADER: error: this mode does not support emitting C++ headers{{$}}
// RESOLVE_IMPORTS_NO_OBJC_HEADER: error: this mode does not support emitting Objective-C or C++ headers{{$}}
// RUN: not %target-swift-frontend -parse -emit-module-interface-path %t %s 2>&1 | %FileCheck -check-prefix=PARSE_NO_INTERFACE %s
// PARSE_NO_INTERFACE: error: this mode does not support emitting module interface files{{$}}

View File

@@ -1,6 +1,6 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend %S/cdecl.swift -typecheck -module-name CdeclFunctions -emit-cxx-header-path %t/functions.h
// RUN: %target-swift-frontend %S/cdecl.swift -typecheck -module-name CdeclFunctions -enable-cxx-interop -emit-clang-header-path %t/functions.h
// RUN: %target-interop-build-clangxx -c %s -I %t -o %t/cdecl-execution.o
// RUN: %target-interop-build-swift %S/cdecl.swift -o %t/cdecl-execution -Xlinker %t/cdecl-execution.o -module-name Functions -Xfrontend -entry-point-function-name -Xfrontend swiftMain

View File

@@ -1,5 +1,5 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend %s -typecheck -module-name CdeclFunctions -emit-cxx-header-path %t/cdecl.h
// RUN: %target-swift-frontend %s -typecheck -module-name CdeclFunctions -enable-cxx-interop -emit-clang-header-path %t/cdecl.h
// RUN: %FileCheck %s < %t/cdecl.h
// RUN: %check-interop-cxx-header-in-clang(%t/cdecl.h)

View File

@@ -1,5 +1,5 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend %s -typecheck -module-name Functions -emit-cxx-header-path %t/functions.h
// RUN: %target-swift-frontend %s -typecheck -module-name Functions -enable-cxx-interop -emit-clang-header-path %t/functions.h
// RUN: %FileCheck %s < %t/functions.h
// RUN: %check-interop-cxx-header-in-clang(%t/functions.h)

View File

@@ -1,6 +1,6 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend %S/swift-functions.swift -typecheck -module-name Functions -emit-cxx-header-path %t/functions.h
// RUN: %target-swift-frontend %S/swift-functions.swift -typecheck -module-name Functions -enable-cxx-interop -emit-clang-header-path %t/functions.h
// RUN: %target-interop-build-clangxx -c %s -I %t -o %t/swift-functions-execution.o
// RUN: %target-interop-build-swift %S/swift-functions.swift -o %t/swift-functions-execution -Xlinker %t/swift-functions-execution.o -module-name Functions -Xfrontend -entry-point-function-name -Xfrontend swiftMain

View File

@@ -1,5 +1,5 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend %s -typecheck -module-name Functions -emit-cxx-header-path %t/functions.h
// RUN: %target-swift-frontend %s -typecheck -module-name Functions -enable-cxx-interop -emit-clang-header-path %t/functions.h
// RUN: %FileCheck %s < %t/functions.h
// RUN: %check-interop-cxx-header-in-clang(%t/functions.h)

View File

@@ -1,5 +1,5 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) %s -typecheck -module-name Test -emit-cxx-header-path %t/empty.h
// RUN: %target-swift-frontend %s -typecheck -module-name Test -enable-cxx-interop -emit-clang-header-path %t/empty.h
// RUN: %FileCheck %s < %t/empty.h
// RUN: %check-interop-cxx-header-in-clang(%t/empty.h)

View File

@@ -1,13 +1,7 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) %s -typecheck -emit-cxx-header-path %t/empty.h
// RUN: %target-swift-frontend %s -typecheck -enable-cxx-interop -emit-clang-header-path %t/empty.h
// RUN: %FileCheck %s < %t/empty.h
// RUN: %check-cxx-header-in-clang -std=c++14 %t/empty.h
// RUN: %check-cxx-header-in-clang -std=c++17 %t/empty.h
// CHECK-NOT: @import Swift;
// CHECK-NOT: IBSegueAction
// CHECK-LABEL: #ifndef EMPTY_SWIFT_H
// CHECK-NEXT: #define EMPTY_SWIFT_H
@@ -63,7 +57,19 @@
// CHECK: # define SWIFT_EXTENSION(M)
// CHECK: # define OBJC_DESIGNATED_INITIALIZER
// CHECK-LABEL: namespace empty {
// CHECK: } // namespace empty
// CHECK-LABEL: #if defined(__OBJC__)
// CHECK-NEXT: #if !defined(IBSegueAction)
// CHECK-NEXT: # define IBSegueAction
// CHECK-NEXT: #endif
// CHECK-LABEL: #if defined(__OBJC__)
// CHECK-NEXT: #if __has_feature(modules)
// CHECK-LABEL: #if defined(__OBJC__)
// CHECK-NEXT: #endif
// CHECK-NEXT: #if defined(__cplusplus)
// CHECK-NEXT: namespace empty {
// CHECK: } // namespace empty
// CHECK: #endif
// CHECK-NOT: @

View File

@@ -424,6 +424,9 @@ SWIFT_CLASS("_TtC8comments13UnorderedList")
- (void)f0;
@end
#endif
#if defined(__cplusplus)
#endif
#if __has_attribute(external_source_symbol)
# pragma clang attribute pop
#endif