Skip to content

[cxx-interop] start emitting a unified header file for a Swift module #41831

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 17, 2022
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
4 changes: 1 addition & 3 deletions include/swift/AST/DiagnosticsFrontend.def
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
3 changes: 1 addition & 2 deletions include/swift/Basic/FileTypes.def
Original file line number Diff line number Diff line change
Expand Up @@ -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", "")
Expand Down
29 changes: 8 additions & 21 deletions include/swift/Basic/SupplementaryOutputPaths.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,17 @@

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
/// 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::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.
Expand Down Expand Up @@ -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())
Expand Down Expand Up @@ -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() &&
Expand Down
3 changes: 1 addition & 2 deletions include/swift/Frontend/Frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,7 @@ class CompilerInvocation {

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;
Expand Down
3 changes: 1 addition & 2 deletions include/swift/Frontend/FrontendInputsAndOutputs.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,7 @@ class FrontendInputsAndOutputs {

bool hasDependenciesPath() const;
bool hasReferenceDependenciesPath() const;
bool hasObjCHeaderOutputPath() const;
bool hasCxxHeaderOutputPath() const;
bool hasClangHeaderOutputPath() const;
bool hasLoadedModuleTracePath() const;
bool hasModuleOutputPath() const;
bool hasModuleDocOutputPath() const;
Expand Down
10 changes: 4 additions & 6 deletions include/swift/Option/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -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]>,
Expand Down
16 changes: 9 additions & 7 deletions include/swift/PrintAsClang/PrintAsClang.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
/// 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.
/// 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 printAsCXX(raw_ostream &os, ModuleDecl *M);
bool printAsClangHeader(raw_ostream &out, ModuleDecl *M,
StringRef bridgingHeader);
}

#endif
9 changes: 3 additions & 6 deletions lib/Basic/FileTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
14 changes: 6 additions & 8 deletions lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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;
}
Expand All @@ -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);
}
}
Expand Down
12 changes: 5 additions & 7 deletions lib/Driver/ToolChains.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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");

Expand Down Expand Up @@ -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()) {
Expand Down
7 changes: 1 addition & 6 deletions lib/Frontend/ArgsToFrontendOptionsConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
50 changes: 20 additions & 30 deletions lib/Frontend/ArgsToFrontendOutputsConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down Expand Up @@ -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 ||
Expand All @@ -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];
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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},
Expand Down Expand Up @@ -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");
Expand Down
Loading