[interop][SwiftToCxx] include the swiftToCxx shim header only when actually needed for reverse interop

This commit is contained in:
Alex Lorenz
2022-10-17 13:12:10 -07:00
parent bec9e54b3b
commit de1e67d054
3 changed files with 45 additions and 35 deletions

View File

@@ -108,8 +108,6 @@ static void writePrologue(raw_ostream &out, ASTContext &ctx,
out << "#include <stdlib.h>\n";
out << "#include <new>\n";
out << "#include <type_traits>\n";
ClangSyntaxPrinter(out).printIncludeForShimHeader(
"_SwiftCxxInteroperability.h");
},
[&] {
out << "#include <stdint.h>\n"
@@ -511,33 +509,44 @@ bool swift::printAsClangHeader(raw_ostream &os, ModuleDecl *M,
bool enableCxx = frontendOpts.ClangHeaderExposedDecls.hasValue() ||
frontendOpts.EnableExperimentalCxxInteropInClangHeader ||
M->DeclContext::getASTContext().LangOpts.EnableCXXInterop;
if (enableCxx) {
bool requiresExplicitExpose = !frontendOpts.ClangHeaderExposedDecls.hasValue() ||
*frontendOpts.ClangHeaderExposedDecls == FrontendOptions::ClangHeaderExposeBehavior::HasExposeAttr;
// Default dependency behavior is used when the -clang-header-expose-decls flag is not specified.
bool defaultDependencyBehavior = !frontendOpts.ClangHeaderExposedDecls.hasValue();
if (!enableCxx)
return;
// Include the shim header only in the C++ mode.
ClangSyntaxPrinter(os).printIncludeForShimHeader(
"_SwiftCxxInteroperability.h");
std::string moduleContentsBuf;
llvm::raw_string_ostream moduleContents{moduleContentsBuf};
auto deps = printModuleContentsAsCxx(moduleContents, *M, interopContext,
/*requiresExposedAttribute=*/requiresExplicitExpose);
// FIXME: In ObjC++ mode, we do not need to reimport duplicate modules.
writeImports(os, deps.imports, *M, bridgingHeader, /*useCxxImport=*/true);
bool requiresExplicitExpose =
!frontendOpts.ClangHeaderExposedDecls.hasValue() ||
*frontendOpts.ClangHeaderExposedDecls ==
FrontendOptions::ClangHeaderExposeBehavior::HasExposeAttr;
// Default dependency behavior is used when the -clang-header-expose-decls
// flag is not specified.
bool defaultDependencyBehavior =
!frontendOpts.ClangHeaderExposedDecls.hasValue();
// Embed the standard library directly.
if (defaultDependencyBehavior && deps.dependsOnStandardLibrary) {
assert(!M->isStdlibModule());
SwiftToClangInteropContext interopContext(*M->getASTContext().getStdlibModule(), irGenOpts);
auto macroGuard =
computeMacroGuard(M->getASTContext().getStdlibModule());
os << "#ifndef " << macroGuard << "\n";
os << "#define " << macroGuard << "\n";
printModuleContentsAsCxx(os, *M->getASTContext().getStdlibModule(), interopContext, /*requiresExposedAttribute=*/true);
os << "#endif // " << macroGuard << "\n";
std::string moduleContentsBuf;
llvm::raw_string_ostream moduleContents{moduleContentsBuf};
auto deps = printModuleContentsAsCxx(
moduleContents, *M, interopContext,
/*requiresExposedAttribute=*/requiresExplicitExpose);
// FIXME: In ObjC++ mode, we do not need to reimport duplicate modules.
writeImports(os, deps.imports, *M, bridgingHeader, /*useCxxImport=*/true);
// Embed the standard library directly.
if (defaultDependencyBehavior && deps.dependsOnStandardLibrary) {
assert(!M->isStdlibModule());
SwiftToClangInteropContext interopContext(
*M->getASTContext().getStdlibModule(), irGenOpts);
auto macroGuard = computeMacroGuard(M->getASTContext().getStdlibModule());
os << "#ifndef " << macroGuard << "\n";
os << "#define " << macroGuard << "\n";
printModuleContentsAsCxx(os, *M->getASTContext().getStdlibModule(),
interopContext,
/*requiresExposedAttribute=*/true);
os << "#endif // " << macroGuard << "\n";
}
os << moduleContents.str();
}
});
writeEpilogue(os);

View File

@@ -32,17 +32,6 @@
// CHECK-NEXT: #include <stdlib.h>
// CHECK-NEXT: #include <new>
// CHECK-NEXT: #include <type_traits>
// CHECK-NEXT: // Look for the C++ interop support header relative to clang's resource dir:
// CHECK-NEXT: // '<toolchain>/usr/lib/clang/<version>/include/../../../swift/swiftToCxx'.
// CHECK-NEXT: #if __has_include(<../../../swift/swiftToCxx/_SwiftCxxInteroperability.h>)
// CHECK-NEXT: #include <../../../swift/swiftToCxx/_SwiftCxxInteroperability.h>
// CHECK-NEXT: #elif __has_include(<../../../../../lib/swift/swiftToCxx/_SwiftCxxInteroperability.h>)
// CHECK-NEXT: // '<toolchain>/usr/local/lib/clang/<version>/include/../../../../../lib/swift/swiftToCxx'.
// CHECK-NEXT: #include <../../../../../lib/swift/swiftToCxx/_SwiftCxxInteroperability.h>
// CHECK-NEXT: // Alternatively, allow user to find the header using additional include path into '<toolchain>/lib/swift'.
// CHECK-NEXT: #elif __has_include(<swiftToCxx/_SwiftCxxInteroperability.h>)
// CHECK-NEXT: #include <swiftToCxx/_SwiftCxxInteroperability.h>
// CHECK-NEXT: #endif
// CHECK-NEXT: #else
// CHECK-NEXT: #include <stdint.h>
// CHECK-NEXT: #include <stddef.h>
@@ -98,6 +87,17 @@
// CHECK-LABEL: #if defined(__OBJC__)
// CHECK-NEXT: #endif
// CHECK-NEXT: #if defined(__cplusplus)
// CHECK-NEXT: // Look for the C++ interop support header relative to clang's resource dir:
// CHECK-NEXT: // '<toolchain>/usr/lib/clang/<version>/include/../../../swift/swiftToCxx'.
// CHECK-NEXT: #if __has_include(<../../../swift/swiftToCxx/_SwiftCxxInteroperability.h>)
// CHECK-NEXT: #include <../../../swift/swiftToCxx/_SwiftCxxInteroperability.h>
// CHECK-NEXT: #elif __has_include(<../../../../../lib/swift/swiftToCxx/_SwiftCxxInteroperability.h>)
// CHECK-NEXT: // '<toolchain>/usr/local/lib/clang/<version>/include/../../../../../lib/swift/swiftToCxx'.
// CHECK-NEXT: #include <../../../../../lib/swift/swiftToCxx/_SwiftCxxInteroperability.h>
// CHECK-NEXT: // Alternatively, allow user to find the header using additional include path into '<toolchain>/lib/swift'.
// CHECK-NEXT: #elif __has_include(<swiftToCxx/_SwiftCxxInteroperability.h>)
// CHECK-NEXT: #include <swiftToCxx/_SwiftCxxInteroperability.h>
// CHECK-NEXT: #endif
// CHECK-NEXT: #if __has_feature(objc_modules)
// CHECK: #ifndef SWIFT_PRINTED_CORE
// CHECK: } // namespace swift

View File

@@ -4,6 +4,7 @@
// RUN: %check-in-clang -std=c99 %t/empty.h
// RUN: %check-in-clang -std=c11 %t/empty.h
// RUN: %check-cxx-header-in-clang -x objective-c++-header -std=c++98 -D_LIBCPP_CSTDLIB %t/empty.h
// RUN: %check-cxx-header-in-clang -x objective-c++-header -std=c++11 -D_LIBCPP_CSTDLIB %t/empty.h
// RUN: %check-cxx-header-in-clang -x objective-c++-header -std=c++14 -D_LIBCPP_CSTDLIB %t/empty.h