mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[cxx-interop] Emit C++ declarations only when '-clang-header-expose-public-decl' is enabled
This fix also ensures that we only emit C++ functions for now
This commit is contained in:
@@ -378,6 +378,10 @@ public:
|
||||
/// '.../lib/swift', otherwise '.../lib/swift_static'.
|
||||
bool UseSharedResourceFolder = true;
|
||||
|
||||
/// Indicates whether to expose all public declarations in the generated clang
|
||||
/// header.
|
||||
bool ExposePublicDeclsInClangHeader = false;
|
||||
|
||||
/// \return true if the given action only parses without doing other compilation steps.
|
||||
static bool shouldActionOnlyParse(ActionType);
|
||||
|
||||
|
||||
@@ -1031,4 +1031,9 @@ def skip_import_in_public_interface:
|
||||
HelpText<"Skip the import statement corresponding to a module name "
|
||||
"when printing the public interface.">;
|
||||
|
||||
def clang_header_expose_public_decls:
|
||||
Flag<["-"], "clang-header-expose-public-decls">,
|
||||
HelpText<"Expose all public declarations in the generated clang header">,
|
||||
Flags<[FrontendOption, HelpHidden]>;
|
||||
|
||||
} // end let Flags = [FrontendOption, NoDriverOption, HelpHidden]
|
||||
|
||||
@@ -26,13 +26,14 @@ namespace swift {
|
||||
/// 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.
|
||||
/// 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 printAsClangHeader(raw_ostream &out, ModuleDecl *M,
|
||||
StringRef bridgingHeader);
|
||||
StringRef bridgingHeader,
|
||||
bool ExposePublicDeclsInClangHeader);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -274,6 +274,8 @@ bool ArgsToFrontendOptionsConverter::convert(
|
||||
Opts.EnableIncrementalDependencyVerifier |= Args.hasArg(OPT_verify_incremental_dependencies);
|
||||
Opts.UseSharedResourceFolder = !Args.hasArg(OPT_use_static_resource_dir);
|
||||
Opts.DisableBuildingInterface = Args.hasArg(OPT_disable_building_interface);
|
||||
Opts.ExposePublicDeclsInClangHeader =
|
||||
Args.hasArg(OPT_clang_header_expose_public_decls);
|
||||
|
||||
computeImportObjCHeaderOptions();
|
||||
computeImplicitImportModuleNames(OPT_import_module, /*isTestable=*/false);
|
||||
|
||||
@@ -179,13 +179,15 @@ static bool writeSIL(SILModule &SM, const PrimarySpecificPaths &PSPs,
|
||||
///
|
||||
/// \see swift::printAsClangHeader
|
||||
static bool printAsClangHeaderIfNeeded(StringRef outputPath, ModuleDecl *M,
|
||||
StringRef bridgingHeader) {
|
||||
StringRef bridgingHeader,
|
||||
bool ExposePublicDeclsInClangHeader) {
|
||||
if (outputPath.empty())
|
||||
return false;
|
||||
return withOutputFile(M->getDiags(), outputPath,
|
||||
[&](raw_ostream &out) -> bool {
|
||||
return printAsClangHeader(out, M, bridgingHeader);
|
||||
});
|
||||
return withOutputFile(
|
||||
M->getDiags(), outputPath, [&](raw_ostream &out) -> bool {
|
||||
return printAsClangHeader(out, M, bridgingHeader,
|
||||
ExposePublicDeclsInClangHeader);
|
||||
});
|
||||
}
|
||||
|
||||
/// Prints the stable module interface for \p M to \p outputPath.
|
||||
@@ -826,7 +828,8 @@ static bool emitAnyWholeModulePostTypeCheckSupplementaryOutputs(
|
||||
}
|
||||
hadAnyError |= printAsClangHeaderIfNeeded(
|
||||
Invocation.getClangHeaderOutputPathForAtMostOnePrimary(),
|
||||
Instance.getMainModule(), BridgingHeaderPathForPrint);
|
||||
Instance.getMainModule(), BridgingHeaderPathForPrint,
|
||||
opts.ExposePublicDeclsInClangHeader);
|
||||
}
|
||||
|
||||
// Only want the header if there's been any errors, ie. there's not much
|
||||
|
||||
@@ -124,13 +124,15 @@ class ModuleWriter {
|
||||
std::vector<const Decl *> declsToWrite;
|
||||
DelayedMemberSet delayedMembers;
|
||||
DeclAndTypePrinter printer;
|
||||
OutputLanguageMode outputLangMode;
|
||||
|
||||
public:
|
||||
ModuleWriter(raw_ostream &os, raw_ostream &prologueOS,
|
||||
llvm::SmallPtrSetImpl<ImportModuleTy> &imports, ModuleDecl &mod,
|
||||
AccessLevel access, OutputLanguageMode outputLang)
|
||||
: os(os), imports(imports), M(mod),
|
||||
printer(M, os, prologueOS, delayedMembers, access, outputLang) {}
|
||||
printer(M, os, prologueOS, delayedMembers, access, outputLang),
|
||||
outputLangMode(outputLang) {}
|
||||
|
||||
/// Returns true if we added the decl's module to the import set, false if
|
||||
/// the decl is a local decl.
|
||||
@@ -576,7 +578,11 @@ public:
|
||||
const Decl *D = declsToWrite.back();
|
||||
bool success = true;
|
||||
|
||||
if (isa<ValueDecl>(D)) {
|
||||
if (outputLangMode == OutputLanguageMode::Cxx) {
|
||||
if (auto FD = dyn_cast<FuncDecl>(D))
|
||||
success = writeFunc(FD);
|
||||
// FIXME: Warn on unsupported exported decl.
|
||||
} else if (isa<ValueDecl>(D)) {
|
||||
if (auto CD = dyn_cast<ClassDecl>(D))
|
||||
success = writeClass(CD);
|
||||
else if (auto PD = dyn_cast<ProtocolDecl>(D))
|
||||
|
||||
@@ -458,7 +458,8 @@ static std::string getModuleContentsCxxString(ModuleDecl &M) {
|
||||
}
|
||||
|
||||
bool swift::printAsClangHeader(raw_ostream &os, ModuleDecl *M,
|
||||
StringRef bridgingHeader) {
|
||||
StringRef bridgingHeader,
|
||||
bool ExposePublicDeclsInClangHeader) {
|
||||
llvm::PrettyStackTraceString trace("While generating Clang header");
|
||||
|
||||
SmallPtrSet<ImportModuleTy, 8> imports;
|
||||
@@ -472,7 +473,7 @@ bool swift::printAsClangHeader(raw_ostream &os, ModuleDecl *M,
|
||||
emitObjCConditional(os, [&] { os << objcModuleContents.str(); });
|
||||
emitCxxConditional(os, [&] {
|
||||
// FIXME: Expose Swift with @expose by default.
|
||||
if (M->getASTContext().LangOpts.EnableCXXInterop) {
|
||||
if (ExposePublicDeclsInClangHeader) {
|
||||
os << getModuleContentsCxxString(*M);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
|
||||
// RUN: %target-swift-frontend %S/cdecl.swift -typecheck -module-name CdeclFunctions -enable-cxx-interop -emit-clang-header-path %t/functions.h
|
||||
// RUN: %target-swift-frontend %S/cdecl.swift -typecheck -module-name CdeclFunctions -clang-header-expose-public-decls -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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-swift-frontend %s -typecheck -module-name CdeclFunctions -enable-cxx-interop -emit-clang-header-path %t/cdecl.h
|
||||
// RUN: %target-swift-frontend %s -typecheck -module-name CdeclFunctions -clang-header-expose-public-decls -emit-clang-header-path %t/cdecl.h
|
||||
// RUN: %FileCheck %s < %t/cdecl.h
|
||||
|
||||
// RUN: %check-interop-cxx-header-in-clang(%t/cdecl.h)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-swift-frontend %s -typecheck -module-name Functions -enable-cxx-interop -emit-clang-header-path %t/functions.h
|
||||
// RUN: %target-swift-frontend %s -typecheck -module-name Functions -clang-header-expose-public-decls -emit-clang-header-path %t/functions.h
|
||||
// RUN: %FileCheck %s < %t/functions.h
|
||||
|
||||
// RUN: %check-interop-cxx-header-in-clang(%t/functions.h)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
|
||||
// RUN: %target-swift-frontend %S/swift-functions.swift -typecheck -module-name Functions -enable-cxx-interop -emit-clang-header-path %t/functions.h
|
||||
// RUN: %target-swift-frontend %S/swift-functions.swift -typecheck -module-name Functions -clang-header-expose-public-decls -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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-swift-frontend %s -typecheck -module-name Functions -enable-cxx-interop -emit-clang-header-path %t/functions.h
|
||||
// RUN: %target-swift-frontend %s -typecheck -module-name Functions -clang-header-expose-public-decls -emit-clang-header-path %t/functions.h
|
||||
// RUN: %FileCheck %s < %t/functions.h
|
||||
|
||||
// RUN: %check-interop-cxx-header-in-clang(%t/functions.h)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-swift-frontend %s -typecheck -module-name Test -enable-cxx-interop -emit-clang-header-path %t/empty.h
|
||||
// RUN: %target-swift-frontend %s -typecheck -module-name Test -clang-header-expose-public-decls -emit-clang-header-path %t/empty.h
|
||||
// RUN: %FileCheck %s < %t/empty.h
|
||||
|
||||
// RUN: %check-interop-cxx-header-in-clang(%t/empty.h)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-swift-frontend %s -typecheck -enable-cxx-interop -emit-clang-header-path %t/empty.h
|
||||
// RUN: %target-swift-frontend %s -typecheck -clang-header-expose-public-decls -emit-clang-header-path %t/empty.h
|
||||
// RUN: %FileCheck %s < %t/empty.h
|
||||
|
||||
// CHECK-LABEL: #ifndef EMPTY_SWIFT_H
|
||||
|
||||
Reference in New Issue
Block a user