@@ -58,6 +58,17 @@ static void emitObjCConditional(raw_ostream &out,
58
58
out << " #endif\n " ;
59
59
}
60
60
61
+ static void emitExternC (raw_ostream &out,
62
+ llvm::function_ref<void ()> cCase) {
63
+ emitCxxConditional (out, [&] {
64
+ out << " extern \" C\" {\n " ;
65
+ });
66
+ cCase ();
67
+ emitCxxConditional (out, [&] {
68
+ out << " } // extern \" C\"\n " ;
69
+ });
70
+ }
71
+
61
72
static void writePtrauthPrologue (raw_ostream &os, ASTContext &ctx) {
62
73
emitCxxConditional (os, [&]() {
63
74
ClangSyntaxPrinter (ctx, os).printIgnoredDiagnosticBlock (
@@ -207,6 +218,21 @@ static void writePrologue(raw_ostream &out, ASTContext &ctx,
207
218
208
219
static_assert (SWIFT_MAX_IMPORTED_SIMD_ELEMENTS == 4 ,
209
220
" need to add SIMD typedefs here if max elements is increased" );
221
+
222
+ if (ctx.LangOpts .hasFeature (Feature::CDecl)) {
223
+ // For C compilers which don’t support nullability attributes, ignore them;
224
+ // for ones which do, suppress warnings about them being an extension.
225
+ out << " #if !__has_feature(nullability)\n "
226
+ " # define _Nonnull\n "
227
+ " # define _Nullable\n "
228
+ " # define _Null_unspecified\n "
229
+ " #elif !defined(__OBJC__)\n "
230
+ " # pragma clang diagnostic ignored \" -Wnullability-extension\"\n "
231
+ " #endif\n "
232
+ " #if !__has_feature(nullability_nullable_result)\n "
233
+ " # define _Nullable_result _Nullable\n "
234
+ " #endif\n " ;
235
+ }
210
236
}
211
237
212
238
static int compareImportModulesByName (const ImportModuleTy *left,
@@ -577,12 +603,21 @@ bool swift::printAsClangHeader(raw_ostream &os, ModuleDecl *M,
577
603
llvm::PrettyStackTraceString trace (" While generating Clang header" );
578
604
579
605
SwiftToClangInteropContext interopContext (*M, irGenOpts);
606
+ writePrologue (os, M->getASTContext (), computeMacroGuard (M));
607
+
608
+ // C content (@cdecl)
609
+ if (M->getASTContext ().LangOpts .hasFeature (Feature::CDecl)) {
610
+ SmallPtrSet<ImportModuleTy, 8 > imports;
611
+ emitExternC (os, [&] {
612
+ printModuleContentsAsC (os, imports, *M, interopContext);
613
+ });
614
+ }
580
615
616
+ // Objective-C content
581
617
SmallPtrSet<ImportModuleTy, 8 > imports;
582
618
std::string objcModuleContentsBuf;
583
619
llvm::raw_string_ostream objcModuleContents{objcModuleContentsBuf};
584
620
printModuleContentsAsObjC (objcModuleContents, imports, *M, interopContext);
585
- writePrologue (os, M->getASTContext (), computeMacroGuard (M));
586
621
emitObjCConditional (os, [&] {
587
622
llvm::StringMap<StringRef> exposedModuleHeaderNames;
588
623
writeImports (os, imports, *M, bridgingHeader, frontendOpts,
@@ -591,6 +626,8 @@ bool swift::printAsClangHeader(raw_ostream &os, ModuleDecl *M,
591
626
writePostImportPrologue (os, *M);
592
627
emitObjCConditional (os, [&] { os << " \n " << objcModuleContents.str (); });
593
628
writeObjCEpilogue (os);
629
+
630
+ // C++ content
594
631
emitCxxConditional (os, [&] {
595
632
// FIXME: Expose Swift with @expose by default.
596
633
bool enableCxx = frontendOpts.ClangHeaderExposedDecls .has_value () ||
0 commit comments