Skip to content

Commit c4cc9e8

Browse files
committed
[interop][SwiftToCxx] do not error out on -Wnon-modular-include-in-framework-module clang diagnostic when importing the generated header as part of a framework back into C++ via a Clang module
1 parent 8378431 commit c4cc9e8

File tree

5 files changed

+126
-23
lines changed

5 files changed

+126
-23
lines changed

lib/PrintAsClang/ClangSyntaxPrinter.cpp

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -378,24 +378,29 @@ void ClangSyntaxPrinter::printPrimaryCxxTypeName(
378378
}
379379

380380
void ClangSyntaxPrinter::printIncludeForShimHeader(StringRef headerName) {
381-
os << "// Look for the C++ interop support header relative to clang's "
382-
"resource dir:\n";
383-
os << "// "
384-
"'<toolchain>/usr/lib/clang/<version>/include/../../../swift/"
385-
"swiftToCxx'.\n";
386-
os << "#if __has_include(<../../../swift/swiftToCxx/" << headerName << ">)\n";
387-
os << "#include <../../../swift/swiftToCxx/" << headerName << ">\n";
388-
os << "#elif __has_include(<../../../../../lib/swift/swiftToCxx/"
389-
<< headerName << ">)\n";
390-
os << "// "
391-
"'<toolchain>/usr/local/lib/clang/<version>/include/../../../../../lib/"
392-
"swift/swiftToCxx'.\n";
393-
os << "#include <../../../../../lib/swift/swiftToCxx/" << headerName << ">\n";
394-
os << "// Alternatively, allow user to find the header using additional "
395-
"include path into '<toolchain>/lib/swift'.\n";
396-
os << "#elif __has_include(<swiftToCxx/" << headerName << ">)\n";
397-
os << "#include <swiftToCxx/" << headerName << ">\n";
398-
os << "#endif\n";
381+
printIgnoredDiagnosticBlock("non-modular-include-in-framework-module", [&] {
382+
os << "// Look for the C++ interop support header relative to clang's "
383+
"resource dir:\n";
384+
os << "// "
385+
"'<toolchain>/usr/lib/clang/<version>/include/../../../swift/"
386+
"swiftToCxx'.\n";
387+
os << "#if __has_include(<../../../swift/swiftToCxx/" << headerName
388+
<< ">)\n";
389+
os << "#include <../../../swift/swiftToCxx/" << headerName << ">\n";
390+
os << "#elif __has_include(<../../../../../lib/swift/swiftToCxx/"
391+
<< headerName << ">)\n";
392+
os << "// "
393+
"'<toolchain>/usr/local/lib/clang/<version>/include/../../../../../"
394+
"lib/"
395+
"swift/swiftToCxx'.\n";
396+
os << "#include <../../../../../lib/swift/swiftToCxx/" << headerName
397+
<< ">\n";
398+
os << "// Alternatively, allow user to find the header using additional "
399+
"include path into '<toolchain>/lib/swift'.\n";
400+
os << "#elif __has_include(<swiftToCxx/" << headerName << ">)\n";
401+
os << "#include <swiftToCxx/" << headerName << ">\n";
402+
os << "#endif\n";
403+
});
399404
}
400405

401406
void ClangSyntaxPrinter::printDefine(StringRef macroName) {

lib/PrintAsClang/PrintAsClang.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,15 @@ static void emitObjCConditional(raw_ostream &out,
5959

6060
static void writePtrauthPrologue(raw_ostream &os) {
6161
emitCxxConditional(os, [&]() {
62-
os << "#if __has_include(<ptrauth.h>)\n";
62+
os << "#if defined(__arm64e__) && __has_include(<ptrauth.h>)\n";
6363
os << "# include <ptrauth.h>\n";
6464
os << "#else\n";
65-
os << "# ifndef __ptrauth_swift_value_witness_function_pointer\n";
66-
os << "# define __ptrauth_swift_value_witness_function_pointer(x)\n";
67-
os << "# endif\n";
65+
ClangSyntaxPrinter(os).printIgnoredDiagnosticBlock(
66+
"reserved-macro-identifier", [&]() {
67+
os << "# ifndef __ptrauth_swift_value_witness_function_pointer\n";
68+
os << "# define __ptrauth_swift_value_witness_function_pointer(x)\n";
69+
os << "# endif\n";
70+
});
6871
os << "#endif\n";
6972
});
7073
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-swift-frontend -typecheck %t/TestFmSwift.swift -typecheck -module-name TestFm -enable-experimental-cxx-interop -emit-clang-header-path %t/TestFm.framework/Headers/TestFm-Swift.h
5+
6+
// RUN: %target-swift-frontend -typecheck %t/SecondSwift.swift -typecheck -module-name Second -enable-experimental-cxx-interop -emit-clang-header-path %t/Second.framework/Headers/Second-Swift.h
7+
8+
// RUN: %target-interop-build-clangxx -std=gnu++17 -fmodules -fcxx-modules -c %t/consumer.cpp -F %t -fsyntax-only -Werror=non-modular-include-in-framework-module
9+
10+
// Check that a client C++ file can use Swift stdlib APIs from two
11+
// mixed-language C++ and Swift frameworks.
12+
13+
// This will only pass on Darwin with -Werror=non-modular-include-in-framework-module,
14+
// as the SDK is not modularized on other platforms.
15+
// REQUIRES: OS=macosx
16+
17+
//--- TestFm.framework/Headers/TestFm.h
18+
#pragma once
19+
20+
class CxxClass {
21+
public:
22+
int testMethod() const {
23+
return 42;
24+
}
25+
};
26+
27+
//--- TestFm.framework/Modules/module.modulemap
28+
framework module TestFm {
29+
umbrella header "TestFm.h"
30+
31+
export *
32+
module * { export * }
33+
}
34+
35+
module TestFm.Swift {
36+
header "TestFm-Swift.h"
37+
}
38+
39+
//--- TestFmSwift.swift
40+
41+
public func testSwiftFunc() -> String {
42+
return ""
43+
}
44+
45+
//--- Second.framework/Headers/Second.h
46+
#pragma once
47+
48+
class CxxSecondClass {
49+
public:
50+
int testMethodTwo() const {
51+
return 42;
52+
}
53+
};
54+
55+
//--- Second.framework/Modules/module.modulemap
56+
framework module Second {
57+
umbrella header "Second.h"
58+
59+
export *
60+
module * { export * }
61+
}
62+
63+
module Second.Swift {
64+
header "Second-Swift.h"
65+
}
66+
67+
//--- SecondSwift.swift
68+
69+
public func testSwiftFuncTwo() -> String {
70+
return ""
71+
}
72+
73+
//--- consumer.cpp
74+
75+
#pragma clang module import TestFm
76+
#pragma clang module import Second
77+
78+
void testUseSwiftStdlibAPIsFromTwoFrameworksImportedViaModules() {
79+
auto swiftString = TestFm::testSwiftFunc();
80+
auto c1 = swiftString.getCount();
81+
auto swiftString2 = Second::testSwiftFuncTwo();
82+
auto c2 = swiftString.getCount();
83+
}

test/Interop/SwiftToCxx/stdlib/swift-stdlib-in-cxx.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@
9090
// CHECK-EMPTY:
9191
// CHECK-NEXT: #endif
9292
// CHECK-NEXT: #define SWIFT_CXX_INTEROP_STRING_MIXIN
93+
// CHECK-NEXT: #pragma clang diagnostic push
94+
// CHECK-NEXT: #pragma clang diagnostic ignored "-Wnon-modular-include-in-framework-module"
9395
// CHECK-NEXT: // Look for the C++ interop support header relative to clang's resource dir:
9496
// CHECK-NEXT: // '<toolchain>/usr/lib/clang/<version>/include/../../../swift/swiftToCxx'.
9597
// CHECK-NEXT: #if __has_include(<../../../swift/swiftToCxx/_SwiftStdlibCxxOverlay.h>)
@@ -101,6 +103,7 @@
101103
// CHECK-NEXT: #elif __has_include(<swiftToCxx/_SwiftStdlibCxxOverlay.h>)
102104
// CHECK-NEXT: #include <swiftToCxx/_SwiftStdlibCxxOverlay.h>
103105
// CHECK-NEXT: #endif
106+
// CHECK-NEXT: #pragma clang diagnostic pop
104107
// CHECK-NEXT: private:
105108

106109
// CHECK: class SWIFT_SYMBOL({{.*}}) UTF8View final {
@@ -114,6 +117,8 @@
114117
// CHECK: SWIFT_INLINE_THUNK swift::Int getCount() const SWIFT_SYMBOL({{.*}});
115118
// CHECK-NEXT: private:
116119

120+
// CHECK: #pragma clang diagnostic push
121+
// CHECK: #pragma clang diagnostic ignored "-Wnon-modular-include-in-framework-module"
117122
// CHECK: #if __has_include(<../../../swift/swiftToCxx/_SwiftStdlibCxxOverlay.h>)
118123
// CHECK-NEXT: #include <../../../swift/swiftToCxx/_SwiftStdlibCxxOverlay.h>
119124
// CHECK-NEXT: #elif __has_include(<../../../../../lib/swift/swiftToCxx/_SwiftStdlibCxxOverlay.h>)
@@ -123,5 +128,6 @@
123128
// CHECK-NEXT: #elif __has_include(<swiftToCxx/_SwiftStdlibCxxOverlay.h>)
124129
// CHECK-NEXT: #include <swiftToCxx/_SwiftStdlibCxxOverlay.h>
125130
// CHECK-NEXT: #endif
131+
// CHECK-NEXTZ: #pragma clang diagnostic pop
126132

127133
// CHECK: } // namespace swift

test/PrintAsCxx/empty.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,15 @@
3939
// CHECK-NEXT: #include <string.h>
4040
// CHECK-NEXT: #endif
4141
// CHECK-NEXT: #if defined(__cplusplus)
42-
// CHECK-NEXT: #if __has_include(<ptrauth.h>)
42+
// CHECK-NEXT: #if defined(__arm64e__) && __has_include(<ptrauth.h>)
4343
// CHECK-NEXT: # include <ptrauth.h>
4444
// CHECK-NEXT: #else
45+
// CHECK-NEXT: #pragma clang diagnostic push
46+
// CHECK-NEXT: #pragma clang diagnostic ignored "-Wreserved-macro-identifier"
4547
// CHECK-NEXT: # ifndef __ptrauth_swift_value_witness_function_pointer
4648
// CHECK-NEXT: # define __ptrauth_swift_value_witness_function_pointer(x)
4749
// CHECK-NEXT: # endif
50+
// CHECK-NEXT: #pragma clang diagnostic pop
4851
// CHECK-NEXT: #endif
4952
// CHECK-NEXT: #endif
5053

@@ -87,6 +90,8 @@
8790
// CHECK-LABEL: #if defined(__OBJC__)
8891
// CHECK-NEXT: #endif
8992
// CHECK-NEXT: #if defined(__cplusplus)
93+
// CHECK-NEXT: #pragma clang diagnostic push
94+
// CHECK-NEXT: #pragma clang diagnostic ignored "-Wnon-modular-include-in-framework-module"
9095
// CHECK-NEXT: // Look for the C++ interop support header relative to clang's resource dir:
9196
// CHECK-NEXT: // '<toolchain>/usr/lib/clang/<version>/include/../../../swift/swiftToCxx'.
9297
// CHECK-NEXT: #if __has_include(<../../../swift/swiftToCxx/_SwiftCxxInteroperability.h>)
@@ -98,6 +103,7 @@
98103
// CHECK-NEXT: #elif __has_include(<swiftToCxx/_SwiftCxxInteroperability.h>)
99104
// CHECK-NEXT: #include <swiftToCxx/_SwiftCxxInteroperability.h>
100105
// CHECK-NEXT: #endif
106+
// CHECK-NEXT: #pragma clang diagnostic pop
101107
// CHECK-NEXT: #if __has_feature(objc_modules)
102108
// CHECK: #ifndef SWIFT_PRINTED_CORE
103109
// CHECK: } // namespace swift

0 commit comments

Comments
 (0)