Skip to content

Commit 80bc75a

Browse files
committed
[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
1 parent 2e3aa87 commit 80bc75a

File tree

14 files changed

+43
-21
lines changed

14 files changed

+43
-21
lines changed

include/swift/Frontend/FrontendOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,10 @@ class FrontendOptions {
378378
/// '.../lib/swift', otherwise '.../lib/swift_static'.
379379
bool UseSharedResourceFolder = true;
380380

381+
/// Indicates whether to expose all public declarations in the generated clang
382+
/// header.
383+
bool ExposePublicDeclsInClangHeader = false;
384+
381385
/// \return true if the given action only parses without doing other compilation steps.
382386
static bool shouldActionOnlyParse(ActionType);
383387

include/swift/Option/FrontendOptions.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,4 +1031,9 @@ def skip_import_in_public_interface:
10311031
HelpText<"Skip the import statement corresponding to a module name "
10321032
"when printing the public interface.">;
10331033

1034+
def clang_header_expose_public_decls:
1035+
Flag<["-"], "clang-header-expose-public-decls">,
1036+
HelpText<"Expose all public declarations in the generated clang header">,
1037+
Flags<[FrontendOption, HelpHidden]>;
1038+
10341039
} // end let Flags = [FrontendOption, NoDriverOption, HelpHidden]

include/swift/PrintAsClang/PrintAsClang.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,14 @@ namespace swift {
2626
/// The Objective-C compatible declarations are printed into a block that
2727
/// ensures that those declarations are only usable when the header is
2828
/// compiled in Objective-C mode.
29-
/// The C++ compatible declarations are printed into a block that ensures
30-
/// that those declarations are only usable when the header is compiled in
31-
/// C++ mode.
29+
/// The C++ compatible declarations are printed into a block that ensures
30+
/// that those declarations are only usable when the header is compiled in
31+
/// C++ mode.
3232
///
3333
/// Returns true on error.
3434
bool printAsClangHeader(raw_ostream &out, ModuleDecl *M,
35-
StringRef bridgingHeader);
35+
StringRef bridgingHeader,
36+
bool ExposePublicDeclsInClangHeader);
3637
}
3738

3839
#endif

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,8 @@ bool ArgsToFrontendOptionsConverter::convert(
274274
Opts.EnableIncrementalDependencyVerifier |= Args.hasArg(OPT_verify_incremental_dependencies);
275275
Opts.UseSharedResourceFolder = !Args.hasArg(OPT_use_static_resource_dir);
276276
Opts.DisableBuildingInterface = Args.hasArg(OPT_disable_building_interface);
277+
Opts.ExposePublicDeclsInClangHeader =
278+
Args.hasArg(OPT_clang_header_expose_public_decls);
277279

278280
computeImportObjCHeaderOptions();
279281
computeImplicitImportModuleNames(OPT_import_module, /*isTestable=*/false);

lib/FrontendTool/FrontendTool.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -179,13 +179,15 @@ static bool writeSIL(SILModule &SM, const PrimarySpecificPaths &PSPs,
179179
///
180180
/// \see swift::printAsClangHeader
181181
static bool printAsClangHeaderIfNeeded(StringRef outputPath, ModuleDecl *M,
182-
StringRef bridgingHeader) {
182+
StringRef bridgingHeader,
183+
bool ExposePublicDeclsInClangHeader) {
183184
if (outputPath.empty())
184185
return false;
185-
return withOutputFile(M->getDiags(), outputPath,
186-
[&](raw_ostream &out) -> bool {
187-
return printAsClangHeader(out, M, bridgingHeader);
188-
});
186+
return withOutputFile(
187+
M->getDiags(), outputPath, [&](raw_ostream &out) -> bool {
188+
return printAsClangHeader(out, M, bridgingHeader,
189+
ExposePublicDeclsInClangHeader);
190+
});
189191
}
190192

191193
/// Prints the stable module interface for \p M to \p outputPath.
@@ -826,7 +828,8 @@ static bool emitAnyWholeModulePostTypeCheckSupplementaryOutputs(
826828
}
827829
hadAnyError |= printAsClangHeaderIfNeeded(
828830
Invocation.getClangHeaderOutputPathForAtMostOnePrimary(),
829-
Instance.getMainModule(), BridgingHeaderPathForPrint);
831+
Instance.getMainModule(), BridgingHeaderPathForPrint,
832+
opts.ExposePublicDeclsInClangHeader);
830833
}
831834

832835
// Only want the header if there's been any errors, ie. there's not much

lib/PrintAsClang/ModuleContentsWriter.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,15 @@ class ModuleWriter {
124124
std::vector<const Decl *> declsToWrite;
125125
DelayedMemberSet delayedMembers;
126126
DeclAndTypePrinter printer;
127+
OutputLanguageMode outputLangMode;
127128

128129
public:
129130
ModuleWriter(raw_ostream &os, raw_ostream &prologueOS,
130131
llvm::SmallPtrSetImpl<ImportModuleTy> &imports, ModuleDecl &mod,
131132
AccessLevel access, OutputLanguageMode outputLang)
132133
: os(os), imports(imports), M(mod),
133-
printer(M, os, prologueOS, delayedMembers, access, outputLang) {}
134+
printer(M, os, prologueOS, delayedMembers, access, outputLang),
135+
outputLangMode(outputLang) {}
134136

135137
/// Returns true if we added the decl's module to the import set, false if
136138
/// the decl is a local decl.
@@ -576,7 +578,11 @@ class ModuleWriter {
576578
const Decl *D = declsToWrite.back();
577579
bool success = true;
578580

579-
if (isa<ValueDecl>(D)) {
581+
if (outputLangMode == OutputLanguageMode::Cxx) {
582+
if (auto FD = dyn_cast<FuncDecl>(D))
583+
success = writeFunc(FD);
584+
// FIXME: Warn on unsupported exported decl.
585+
} else if (isa<ValueDecl>(D)) {
580586
if (auto CD = dyn_cast<ClassDecl>(D))
581587
success = writeClass(CD);
582588
else if (auto PD = dyn_cast<ProtocolDecl>(D))

lib/PrintAsClang/PrintAsClang.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,8 @@ static std::string getModuleContentsCxxString(ModuleDecl &M) {
458458
}
459459

460460
bool swift::printAsClangHeader(raw_ostream &os, ModuleDecl *M,
461-
StringRef bridgingHeader) {
461+
StringRef bridgingHeader,
462+
bool ExposePublicDeclsInClangHeader) {
462463
llvm::PrettyStackTraceString trace("While generating Clang header");
463464

464465
SmallPtrSet<ImportModuleTy, 8> imports;
@@ -472,7 +473,7 @@ bool swift::printAsClangHeader(raw_ostream &os, ModuleDecl *M,
472473
emitObjCConditional(os, [&] { os << objcModuleContents.str(); });
473474
emitCxxConditional(os, [&] {
474475
// FIXME: Expose Swift with @expose by default.
475-
if (M->getASTContext().LangOpts.EnableCXXInterop) {
476+
if (ExposePublicDeclsInClangHeader) {
476477
os << getModuleContentsCxxString(*M);
477478
}
478479
});

test/Interop/SwiftToCxx/functions/cdecl-execution.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %empty-directory(%t)
22

3-
// RUN: %target-swift-frontend %S/cdecl.swift -typecheck -module-name CdeclFunctions -enable-cxx-interop -emit-clang-header-path %t/functions.h
3+
// RUN: %target-swift-frontend %S/cdecl.swift -typecheck -module-name CdeclFunctions -clang-header-expose-public-decls -emit-clang-header-path %t/functions.h
44

55
// RUN: %target-interop-build-clangxx -c %s -I %t -o %t/cdecl-execution.o
66
// 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

test/Interop/SwiftToCxx/functions/cdecl.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-swift-frontend %s -typecheck -module-name CdeclFunctions -enable-cxx-interop -emit-clang-header-path %t/cdecl.h
2+
// RUN: %target-swift-frontend %s -typecheck -module-name CdeclFunctions -clang-header-expose-public-decls -emit-clang-header-path %t/cdecl.h
33
// RUN: %FileCheck %s < %t/cdecl.h
44

55
// RUN: %check-interop-cxx-header-in-clang(%t/cdecl.h)

test/Interop/SwiftToCxx/functions/function-availability.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-swift-frontend %s -typecheck -module-name Functions -enable-cxx-interop -emit-clang-header-path %t/functions.h
2+
// RUN: %target-swift-frontend %s -typecheck -module-name Functions -clang-header-expose-public-decls -emit-clang-header-path %t/functions.h
33
// RUN: %FileCheck %s < %t/functions.h
44

55
// RUN: %check-interop-cxx-header-in-clang(%t/functions.h)

test/Interop/SwiftToCxx/functions/swift-functions-execution.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %empty-directory(%t)
22

3-
// RUN: %target-swift-frontend %S/swift-functions.swift -typecheck -module-name Functions -enable-cxx-interop -emit-clang-header-path %t/functions.h
3+
// RUN: %target-swift-frontend %S/swift-functions.swift -typecheck -module-name Functions -clang-header-expose-public-decls -emit-clang-header-path %t/functions.h
44

55
// RUN: %target-interop-build-clangxx -c %s -I %t -o %t/swift-functions-execution.o
66
// 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

test/Interop/SwiftToCxx/functions/swift-functions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-swift-frontend %s -typecheck -module-name Functions -enable-cxx-interop -emit-clang-header-path %t/functions.h
2+
// RUN: %target-swift-frontend %s -typecheck -module-name Functions -clang-header-expose-public-decls -emit-clang-header-path %t/functions.h
33
// RUN: %FileCheck %s < %t/functions.h
44

55
// RUN: %check-interop-cxx-header-in-clang(%t/functions.h)

test/Interop/SwiftToCxx/module/module-to-namespace.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-swift-frontend %s -typecheck -module-name Test -enable-cxx-interop -emit-clang-header-path %t/empty.h
2+
// RUN: %target-swift-frontend %s -typecheck -module-name Test -clang-header-expose-public-decls -emit-clang-header-path %t/empty.h
33
// RUN: %FileCheck %s < %t/empty.h
44

55
// RUN: %check-interop-cxx-header-in-clang(%t/empty.h)

test/PrintAsCxx/empty.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-swift-frontend %s -typecheck -enable-cxx-interop -emit-clang-header-path %t/empty.h
2+
// RUN: %target-swift-frontend %s -typecheck -clang-header-expose-public-decls -emit-clang-header-path %t/empty.h
33
// RUN: %FileCheck %s < %t/empty.h
44

55
// CHECK-LABEL: #ifndef EMPTY_SWIFT_H

0 commit comments

Comments
 (0)