[cxx-interop] Make reverse interop header compile in embedded mode

These are the minimal changes to make the reverse interop header compile
when embedded Swift is used. Previously, the _SwiftStdlibCxxOverlay.h
and the generated interop header disagreed on the mangling of a symbol.

This is not sufficient yet to use the embedded Swift standard library from
reverse interop, there are some missing symbols while linking. But this
PR enables doing reverse interop without using the stdlib types like
swift::String in C++. Follow-up PRs will fix the rest of the issues.

rdar://154740225
This commit is contained in:
Gabor Horvath
2025-08-18 13:05:56 +01:00
parent 299f17395c
commit ad502146b3
3 changed files with 44 additions and 10 deletions

View File

@@ -29,6 +29,7 @@
#include "swift/AST/SwiftNameTranslation.h"
#include "swift/AST/TypeDeclFinder.h"
#include "swift/Basic/Assertions.h"
#include "swift/Basic/Feature.h"
#include "swift/Basic/SourceManager.h"
#include "swift/ClangImporter/ClangImporter.h"
#include "swift/SIL/SILInstruction.h"
@@ -1183,13 +1184,14 @@ EmittedClangHeaderDependencyInfo swift::printModuleContentsAsCxx(
std::string modulePrologueBuf;
llvm::raw_string_ostream prologueOS{modulePrologueBuf};
EmittedClangHeaderDependencyInfo info;
auto &context = M.getASTContext();
// Define the `SWIFT_SYMBOL` macro.
os << "#ifdef SWIFT_SYMBOL\n";
os << "#undef SWIFT_SYMBOL\n";
os << "#endif\n";
os << "#define SWIFT_SYMBOL(usrValue) SWIFT_SYMBOL_MODULE_USR(\"";
ClangSyntaxPrinter(M.getASTContext(), os).printBaseName(&M);
ClangSyntaxPrinter(context, os).printBaseName(&M);
os << "\", usrValue)\n";
// FIXME: Use getRequiredAccess once @expose is supported.
@@ -1204,9 +1206,11 @@ EmittedClangHeaderDependencyInfo swift::printModuleContentsAsCxx(
os << "#include <string>\n";
os << "#endif\n";
os << "#include <new>\n";
if (context.LangOpts.hasFeature(Feature::Embedded))
os << "#define __EmbeddedSwift__\n";
// Embed an overlay for the standard library.
ClangSyntaxPrinter(M.getASTContext(), moduleOS).printIncludeForShimHeader(
"_SwiftStdlibCxxOverlay.h");
ClangSyntaxPrinter(context, moduleOS)
.printIncludeForShimHeader("_SwiftStdlibCxxOverlay.h");
// Ignore typos in Swift stdlib doc comments.
os << "#pragma clang diagnostic push\n";
os << "#pragma clang diagnostic ignored \"-Wdocumentation\"\n";
@@ -1214,7 +1218,7 @@ EmittedClangHeaderDependencyInfo swift::printModuleContentsAsCxx(
os << "#ifndef SWIFT_PRINTED_CORE\n";
os << "#define SWIFT_PRINTED_CORE\n";
printSwiftToClangCoreScaffold(interopContext, M.getASTContext(),
printSwiftToClangCoreScaffold(interopContext, context,
writer.getTypeMapping(), os);
os << "#endif\n";
@@ -1226,9 +1230,9 @@ EmittedClangHeaderDependencyInfo swift::printModuleContentsAsCxx(
os << "#endif\n";
os << "#ifdef __cplusplus\n";
os << "namespace ";
ClangSyntaxPrinter(M.getASTContext(), os).printBaseName(&M);
ClangSyntaxPrinter(context, os).printBaseName(&M);
os << " SWIFT_PRIVATE_ATTR";
ClangSyntaxPrinter(M.getASTContext(), os).printSymbolUSRAttribute(&M);
ClangSyntaxPrinter(context, os).printSymbolUSRAttribute(&M);
os << " {\n";
os << "namespace " << cxx_synthesis::getCxxImplNamespaceName() << " {\n";
os << "extern \"C\" {\n";
@@ -1246,10 +1250,13 @@ EmittedClangHeaderDependencyInfo swift::printModuleContentsAsCxx(
os << "#pragma clang diagnostic push\n";
os << "#pragma clang diagnostic ignored \"-Wreserved-identifier\"\n";
// Construct a C++ namespace for the module.
ClangSyntaxPrinter(M.getASTContext(), os).printNamespace(
[&](raw_ostream &os) { ClangSyntaxPrinter(M.getASTContext(), os).printBaseName(&M); },
[&](raw_ostream &os) { os << moduleOS.str(); },
ClangSyntaxPrinter::NamespaceTrivia::AttributeSwiftPrivate, &M);
ClangSyntaxPrinter(context, os)
.printNamespace(
[&](raw_ostream &os) {
ClangSyntaxPrinter(context, os).printBaseName(&M);
},
[&](raw_ostream &os) { os << moduleOS.str(); },
ClangSyntaxPrinter::NamespaceTrivia::AttributeSwiftPrivate, &M);
os << "#pragma clang diagnostic pop\n";
if (M.isStdlibModule()) {