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'.
|
/// '.../lib/swift', otherwise '.../lib/swift_static'.
|
||||||
bool UseSharedResourceFolder = true;
|
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.
|
/// \return true if the given action only parses without doing other compilation steps.
|
||||||
static bool shouldActionOnlyParse(ActionType);
|
static bool shouldActionOnlyParse(ActionType);
|
||||||
|
|
||||||
|
|||||||
@@ -1031,4 +1031,9 @@ def skip_import_in_public_interface:
|
|||||||
HelpText<"Skip the import statement corresponding to a module name "
|
HelpText<"Skip the import statement corresponding to a module name "
|
||||||
"when printing the public interface.">;
|
"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]
|
} // end let Flags = [FrontendOption, NoDriverOption, HelpHidden]
|
||||||
|
|||||||
@@ -26,13 +26,14 @@ namespace swift {
|
|||||||
/// The Objective-C compatible declarations are printed into a block that
|
/// The Objective-C compatible declarations are printed into a block that
|
||||||
/// ensures that those declarations are only usable when the header is
|
/// ensures that those declarations are only usable when the header is
|
||||||
/// compiled in Objective-C mode.
|
/// compiled in Objective-C mode.
|
||||||
/// The C++ compatible declarations are printed into a block that ensures
|
/// The C++ compatible declarations are printed into a block that ensures
|
||||||
/// that those declarations are only usable when the header is compiled in
|
/// that those declarations are only usable when the header is compiled in
|
||||||
/// C++ mode.
|
/// C++ mode.
|
||||||
///
|
///
|
||||||
/// Returns true on error.
|
/// Returns true on error.
|
||||||
bool printAsClangHeader(raw_ostream &out, ModuleDecl *M,
|
bool printAsClangHeader(raw_ostream &out, ModuleDecl *M,
|
||||||
StringRef bridgingHeader);
|
StringRef bridgingHeader,
|
||||||
|
bool ExposePublicDeclsInClangHeader);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -274,6 +274,8 @@ bool ArgsToFrontendOptionsConverter::convert(
|
|||||||
Opts.EnableIncrementalDependencyVerifier |= Args.hasArg(OPT_verify_incremental_dependencies);
|
Opts.EnableIncrementalDependencyVerifier |= Args.hasArg(OPT_verify_incremental_dependencies);
|
||||||
Opts.UseSharedResourceFolder = !Args.hasArg(OPT_use_static_resource_dir);
|
Opts.UseSharedResourceFolder = !Args.hasArg(OPT_use_static_resource_dir);
|
||||||
Opts.DisableBuildingInterface = Args.hasArg(OPT_disable_building_interface);
|
Opts.DisableBuildingInterface = Args.hasArg(OPT_disable_building_interface);
|
||||||
|
Opts.ExposePublicDeclsInClangHeader =
|
||||||
|
Args.hasArg(OPT_clang_header_expose_public_decls);
|
||||||
|
|
||||||
computeImportObjCHeaderOptions();
|
computeImportObjCHeaderOptions();
|
||||||
computeImplicitImportModuleNames(OPT_import_module, /*isTestable=*/false);
|
computeImplicitImportModuleNames(OPT_import_module, /*isTestable=*/false);
|
||||||
|
|||||||
@@ -179,13 +179,15 @@ static bool writeSIL(SILModule &SM, const PrimarySpecificPaths &PSPs,
|
|||||||
///
|
///
|
||||||
/// \see swift::printAsClangHeader
|
/// \see swift::printAsClangHeader
|
||||||
static bool printAsClangHeaderIfNeeded(StringRef outputPath, ModuleDecl *M,
|
static bool printAsClangHeaderIfNeeded(StringRef outputPath, ModuleDecl *M,
|
||||||
StringRef bridgingHeader) {
|
StringRef bridgingHeader,
|
||||||
|
bool ExposePublicDeclsInClangHeader) {
|
||||||
if (outputPath.empty())
|
if (outputPath.empty())
|
||||||
return false;
|
return false;
|
||||||
return withOutputFile(M->getDiags(), outputPath,
|
return withOutputFile(
|
||||||
[&](raw_ostream &out) -> bool {
|
M->getDiags(), outputPath, [&](raw_ostream &out) -> bool {
|
||||||
return printAsClangHeader(out, M, bridgingHeader);
|
return printAsClangHeader(out, M, bridgingHeader,
|
||||||
});
|
ExposePublicDeclsInClangHeader);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prints the stable module interface for \p M to \p outputPath.
|
/// Prints the stable module interface for \p M to \p outputPath.
|
||||||
@@ -826,7 +828,8 @@ static bool emitAnyWholeModulePostTypeCheckSupplementaryOutputs(
|
|||||||
}
|
}
|
||||||
hadAnyError |= printAsClangHeaderIfNeeded(
|
hadAnyError |= printAsClangHeaderIfNeeded(
|
||||||
Invocation.getClangHeaderOutputPathForAtMostOnePrimary(),
|
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
|
// 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;
|
std::vector<const Decl *> declsToWrite;
|
||||||
DelayedMemberSet delayedMembers;
|
DelayedMemberSet delayedMembers;
|
||||||
DeclAndTypePrinter printer;
|
DeclAndTypePrinter printer;
|
||||||
|
OutputLanguageMode outputLangMode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ModuleWriter(raw_ostream &os, raw_ostream &prologueOS,
|
ModuleWriter(raw_ostream &os, raw_ostream &prologueOS,
|
||||||
llvm::SmallPtrSetImpl<ImportModuleTy> &imports, ModuleDecl &mod,
|
llvm::SmallPtrSetImpl<ImportModuleTy> &imports, ModuleDecl &mod,
|
||||||
AccessLevel access, OutputLanguageMode outputLang)
|
AccessLevel access, OutputLanguageMode outputLang)
|
||||||
: os(os), imports(imports), M(mod),
|
: 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
|
/// Returns true if we added the decl's module to the import set, false if
|
||||||
/// the decl is a local decl.
|
/// the decl is a local decl.
|
||||||
@@ -576,7 +578,11 @@ public:
|
|||||||
const Decl *D = declsToWrite.back();
|
const Decl *D = declsToWrite.back();
|
||||||
bool success = true;
|
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))
|
if (auto CD = dyn_cast<ClassDecl>(D))
|
||||||
success = writeClass(CD);
|
success = writeClass(CD);
|
||||||
else if (auto PD = dyn_cast<ProtocolDecl>(D))
|
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,
|
bool swift::printAsClangHeader(raw_ostream &os, ModuleDecl *M,
|
||||||
StringRef bridgingHeader) {
|
StringRef bridgingHeader,
|
||||||
|
bool ExposePublicDeclsInClangHeader) {
|
||||||
llvm::PrettyStackTraceString trace("While generating Clang header");
|
llvm::PrettyStackTraceString trace("While generating Clang header");
|
||||||
|
|
||||||
SmallPtrSet<ImportModuleTy, 8> imports;
|
SmallPtrSet<ImportModuleTy, 8> imports;
|
||||||
@@ -472,7 +473,7 @@ bool swift::printAsClangHeader(raw_ostream &os, ModuleDecl *M,
|
|||||||
emitObjCConditional(os, [&] { os << objcModuleContents.str(); });
|
emitObjCConditional(os, [&] { os << objcModuleContents.str(); });
|
||||||
emitCxxConditional(os, [&] {
|
emitCxxConditional(os, [&] {
|
||||||
// FIXME: Expose Swift with @expose by default.
|
// FIXME: Expose Swift with @expose by default.
|
||||||
if (M->getASTContext().LangOpts.EnableCXXInterop) {
|
if (ExposePublicDeclsInClangHeader) {
|
||||||
os << getModuleContentsCxxString(*M);
|
os << getModuleContentsCxxString(*M);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// RUN: %empty-directory(%t)
|
// 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-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
|
// 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: %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: %FileCheck %s < %t/cdecl.h
|
||||||
|
|
||||||
// RUN: %check-interop-cxx-header-in-clang(%t/cdecl.h)
|
// RUN: %check-interop-cxx-header-in-clang(%t/cdecl.h)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// RUN: %empty-directory(%t)
|
// 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: %FileCheck %s < %t/functions.h
|
||||||
|
|
||||||
// RUN: %check-interop-cxx-header-in-clang(%t/functions.h)
|
// RUN: %check-interop-cxx-header-in-clang(%t/functions.h)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// RUN: %empty-directory(%t)
|
// 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-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
|
// 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: %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: %FileCheck %s < %t/functions.h
|
||||||
|
|
||||||
// RUN: %check-interop-cxx-header-in-clang(%t/functions.h)
|
// RUN: %check-interop-cxx-header-in-clang(%t/functions.h)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// RUN: %empty-directory(%t)
|
// 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: %FileCheck %s < %t/empty.h
|
||||||
|
|
||||||
// RUN: %check-interop-cxx-header-in-clang(%t/empty.h)
|
// RUN: %check-interop-cxx-header-in-clang(%t/empty.h)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// RUN: %empty-directory(%t)
|
// 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
|
// RUN: %FileCheck %s < %t/empty.h
|
||||||
|
|
||||||
// CHECK-LABEL: #ifndef EMPTY_SWIFT_H
|
// CHECK-LABEL: #ifndef EMPTY_SWIFT_H
|
||||||
|
|||||||
Reference in New Issue
Block a user