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

View File

@@ -32,17 +32,6 @@
// CHECK-NEXT: #include <stdlib.h> // CHECK-NEXT: #include <stdlib.h>
// CHECK-NEXT: #include <new> // CHECK-NEXT: #include <new>
// CHECK-NEXT: #include <type_traits> // 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: #else
// CHECK-NEXT: #include <stdint.h> // CHECK-NEXT: #include <stdint.h>
// CHECK-NEXT: #include <stddef.h> // CHECK-NEXT: #include <stddef.h>
@@ -98,6 +87,17 @@
// CHECK-LABEL: #if defined(__OBJC__) // CHECK-LABEL: #if defined(__OBJC__)
// CHECK-NEXT: #endif // CHECK-NEXT: #endif
// CHECK-NEXT: #if defined(__cplusplus) // 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-NEXT: #if __has_feature(objc_modules)
// CHECK: #ifndef SWIFT_PRINTED_CORE // CHECK: #ifndef SWIFT_PRINTED_CORE
// CHECK: } // namespace swift // CHECK: } // namespace swift

View File

@@ -4,6 +4,7 @@
// RUN: %check-in-clang -std=c99 %t/empty.h // RUN: %check-in-clang -std=c99 %t/empty.h
// RUN: %check-in-clang -std=c11 %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++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 // RUN: %check-cxx-header-in-clang -x objective-c++-header -std=c++14 -D_LIBCPP_CSTDLIB %t/empty.h