Skip to content

Commit 0312e06

Browse files
committed
[interop][SwiftToCxxToSwift] hide reverse interop module namespaces from forward interop
1 parent fdababa commit 0312e06

25 files changed

+98
-46
lines changed

lib/ClangImporter/ImportDecl.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -1089,6 +1089,9 @@ namespace {
10891089

10901090
Decl *VisitNamespaceDecl(const clang::NamespaceDecl *decl) {
10911091
DeclContext *dc = nullptr;
1092+
// Do not import namespace declarations marked as 'swift_private'.
1093+
if (decl->hasAttr<clang::SwiftPrivateAttr>())
1094+
return nullptr;
10921095
// If this is a top-level namespace, don't put it in the module we're
10931096
// importing, put it in the "__ObjC" module that is implicitly imported.
10941097
if (!decl->getParent()->isNamespace())

lib/PrintAsClang/ClangSyntaxPrinter.cpp

+17-6
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,13 @@ bool ClangSyntaxPrinter::isClangKeyword(Identifier name) {
5050
return ClangSyntaxPrinter::isClangKeyword(name.str());
5151
}
5252

53-
void ClangSyntaxPrinter::printIdentifier(StringRef name) {
53+
void ClangSyntaxPrinter::printIdentifier(StringRef name) const {
5454
os << name;
5555
if (ClangSyntaxPrinter::isClangKeyword(name))
5656
os << '_';
5757
}
5858

59-
void ClangSyntaxPrinter::printBaseName(const ValueDecl *decl) {
59+
void ClangSyntaxPrinter::printBaseName(const ValueDecl *decl) const {
6060
assert(decl->getName().isSimpleName());
6161
printIdentifier(cxx_translation::getNameForCxx(decl));
6262
}
@@ -136,12 +136,23 @@ void ClangSyntaxPrinter::printNominalTypeQualifier(
136136
os << "::";
137137
}
138138

139+
void ClangSyntaxPrinter::printModuleNamespaceStart(
140+
const ModuleDecl &moduleContext) const {
141+
os << "namespace ";
142+
printBaseName(&moduleContext);
143+
os << " __attribute__((swift_private))";
144+
os << " {\n";
145+
}
146+
139147
/// Print a C++ namespace declaration with the give name and body.
140148
void ClangSyntaxPrinter::printNamespace(
141149
llvm::function_ref<void(raw_ostream &OS)> namePrinter,
142-
llvm::function_ref<void(raw_ostream &OS)> bodyPrinter) const {
150+
llvm::function_ref<void(raw_ostream &OS)> bodyPrinter,
151+
NamespaceTrivia trivia) const {
143152
os << "namespace ";
144153
namePrinter(os);
154+
if (trivia == NamespaceTrivia::AttributeSwiftPrivate)
155+
os << " __attribute__((swift_private))";
145156
os << " {\n\n";
146157
bodyPrinter(os);
147158
os << "\n} // namespace ";
@@ -150,9 +161,9 @@ void ClangSyntaxPrinter::printNamespace(
150161
}
151162

152163
void ClangSyntaxPrinter::printNamespace(
153-
StringRef name,
154-
llvm::function_ref<void(raw_ostream &OS)> bodyPrinter) const {
155-
printNamespace([&](raw_ostream &os) { os << name; }, bodyPrinter);
164+
StringRef name, llvm::function_ref<void(raw_ostream &OS)> bodyPrinter,
165+
NamespaceTrivia trivia) const {
166+
printNamespace([&](raw_ostream &os) { os << name; }, bodyPrinter, trivia);
156167
}
157168

158169
void ClangSyntaxPrinter::printExternC(

lib/PrintAsClang/ClangSyntaxPrinter.h

+12-8
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ class ClangSyntaxPrinter {
5050

5151
/// Print a given identifier. If the identifer conflicts with a keyword, add a
5252
/// trailing underscore.
53-
void printIdentifier(StringRef name);
53+
void printIdentifier(StringRef name) const;
5454

5555
/// Print the base name of the given declaration.
56-
void printBaseName(const ValueDecl *decl);
56+
void printBaseName(const ValueDecl *decl) const;
5757

5858
/// Print the C-style prefix for the given module name, that's used for
5959
/// C type names inside the module.
@@ -118,14 +118,18 @@ class ClangSyntaxPrinter {
118118
void printNominalTypeQualifier(const NominalTypeDecl *typeDecl,
119119
const ModuleDecl *moduleContext);
120120

121+
enum class NamespaceTrivia { None, AttributeSwiftPrivate };
122+
123+
void printModuleNamespaceStart(const ModuleDecl &moduleContext) const;
124+
121125
/// Print a C++ namespace declaration with the give name and body.
122-
void
123-
printNamespace(llvm::function_ref<void(raw_ostream &OS)> namePrinter,
124-
llvm::function_ref<void(raw_ostream &OS)> bodyPrinter) const;
126+
void printNamespace(llvm::function_ref<void(raw_ostream &OS)> namePrinter,
127+
llvm::function_ref<void(raw_ostream &OS)> bodyPrinter,
128+
NamespaceTrivia trivia = NamespaceTrivia::None) const;
125129

126-
void
127-
printNamespace(StringRef name,
128-
llvm::function_ref<void(raw_ostream &OS)> bodyPrinter) const;
130+
void printNamespace(StringRef name,
131+
llvm::function_ref<void(raw_ostream &OS)> bodyPrinter,
132+
NamespaceTrivia trivia = NamespaceTrivia::None) const;
129133

130134
/// Print an extern C block with given body.
131135
void

lib/PrintAsClang/ModuleContentsWriter.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,7 @@ EmittedClangHeaderDependencyInfo swift::printModuleContentsAsCxx(
783783
os << "#ifdef __cplusplus\n";
784784
os << "namespace ";
785785
M.ValueDecl::getName().print(os);
786+
os << " __attribute__((swift_private))";
786787
os << " {\n";
787788
os << "namespace " << cxx_synthesis::getCxxImplNamespaceName() << " {\n";
788789
os << "extern \"C\" {\n";
@@ -800,6 +801,7 @@ EmittedClangHeaderDependencyInfo swift::printModuleContentsAsCxx(
800801
// Construct a C++ namespace for the module.
801802
ClangSyntaxPrinter(os).printNamespace(
802803
[&](raw_ostream &os) { M.ValueDecl::getName().print(os); },
803-
[&](raw_ostream &os) { os << moduleOS.str(); });
804+
[&](raw_ostream &os) { os << moduleOS.str(); },
805+
ClangSyntaxPrinter::NamespaceTrivia::AttributeSwiftPrivate);
804806
return info;
805807
}

lib/PrintAsClang/PrintClangValueType.cpp

+4-6
Original file line numberDiff line numberDiff line change
@@ -496,9 +496,8 @@ void ClangValueTypePrinter::printTypePrecedingGenericTraits(
496496
}
497497
os << "#pragma clang diagnostic pop\n";
498498
os << "} // namespace swift\n";
499-
os << "\nnamespace ";
500-
printer.printBaseName(moduleContext);
501-
os << " {\n";
499+
os << "\n";
500+
printer.printModuleNamespaceStart(*moduleContext);
502501
}
503502

504503
void ClangValueTypePrinter::printTypeGenericTraits(
@@ -592,7 +591,6 @@ void ClangValueTypePrinter::printTypeGenericTraits(
592591
os << "} // namespace\n";
593592
os << "#pragma clang diagnostic pop\n";
594593
os << "} // namespace swift\n";
595-
os << "\nnamespace ";
596-
printer.printBaseName(moduleContext);
597-
os << " {\n";
594+
os << "\n";
595+
printer.printModuleNamespaceStart(*moduleContext);
598596
}

test/Interop/SwiftToCxx/class/swift-actor-in-cxx.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public final actor ActorWithField {
3030
}
3131
}
3232

33-
// CHECK: namespace Actor {
33+
// CHECK: namespace Actor __attribute__((swift_private)) {
3434
// CHECK: SWIFT_EXTERN void * _Nonnull $s5Actor0A9WithFieldCACycfC(SWIFT_CONTEXT void * _Nonnull _self) SWIFT_NOEXCEPT SWIFT_CALL; // init()
3535
// CHECK: SWIFT_EXTERN void $s5Actor0A9WithFieldC6methodyyF(SWIFT_CONTEXT void * _Nonnull _self) SWIFT_NOEXCEPT SWIFT_CALL; // method()
3636

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ public final class ClassWithIntField {
2121
}
2222
}
2323

24-
// CHECK: namespace Class {
24+
// CHECK: namespace Class __attribute__((swift_private)) {
2525

2626
// CHECK: SWIFT_EXTERN void * _Nonnull $s5Class011passThroughA12WithIntFieldyAA0adeF0CADF(void * _Nonnull x) SWIFT_NOEXCEPT SWIFT_CALL; // passThroughClassWithIntField(_:)
2727
// CHECK-NEXT: SWIFT_EXTERN void * _Nonnull $s5Class06returnA12WithIntFieldAA0acdE0CyF(void) SWIFT_NOEXCEPT SWIFT_CALL; // returnClassWithIntField()
2828
// CHECK-NEXT: SWIFT_EXTERN void $s5Class04takeA12WithIntFieldyyAA0acdE0CF(void * _Nonnull x) SWIFT_NOEXCEPT SWIFT_CALL; // takeClassWithIntField(_:)
2929
// CHECK-NEXT: SWIFT_EXTERN void $s5Class04takeA17WithIntFieldInoutyyAA0acdE0CzF(void * _Nonnull * _Nonnull x) SWIFT_NOEXCEPT SWIFT_CALL; // takeClassWithIntFieldInout(_:)
3030

31-
// CHECK: namespace Class {
31+
// CHECK: namespace Class __attribute__((swift_private)) {
3232

3333
// CHECK: class ClassWithIntField;
3434
// CHECK-NEXT: } // end namespace
@@ -43,7 +43,7 @@ public final class ClassWithIntField {
4343
// CHECK-NEXT: } // namespace swift
4444

4545
// CHECK: namespace
46-
// CHECK-SAME: Class {
46+
// CHECK-SAME: Class __attribute__((swift_private)) {
4747

4848
// CHECK: namespace
4949
// CHECK-SAME: _impl {
@@ -92,7 +92,7 @@ public final class ClassWithIntField {
9292
// CHECK-NEXT: #pragma clang diagnostic pop
9393
// CHECK-NEXT: } // namespace swift
9494
// CHECK-EMPTY:
95-
// CHECK-NEXT: namespace Class {
95+
// CHECK-NEXT: namespace Class __attribute__((swift_private)) {
9696

9797
// CHECK: inline ClassWithIntField passThroughClassWithIntField(const ClassWithIntField& x) noexcept SWIFT_WARN_UNUSED_RESULT {
9898
// CHECK-NEXT: return _impl::_impl_ClassWithIntField::makeRetained(_impl::$s5Class011passThroughA12WithIntFieldyAA0adeF0CADF(::swift::_impl::_impl_RefCountedClass::getOpaquePointer(x)));

test/Interop/SwiftToCxx/core/gen-header-for-module.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@ public func reprintedInImportedModule() -> Int {
2222
return 42
2323
}
2424

25-
// CHECK: namespace Core {
25+
// CHECK: namespace Core __attribute__((swift_private)) {
2626
// CHECK: swift::Int reprintedInImportedModule() noexcept SWIFT_WARN_UNUSED_RESULT {

test/Interop/SwiftToCxx/enums/swift-enum-implementation.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ public struct S {
166166
// CHECK-NEXT: #endif
167167
// CHECK-NEXT: vwTable->initializeWithTake(destStorage, srcStorage, metadata._0);
168168
// CHECK-NEXT: }
169-
// CHECK: namespace Enums {
169+
// CHECK: namespace Enums __attribute__((swift_private)) {
170170
// CHECK: inline E E::_impl_x::operator()(double val) const {
171171
// CHECK-NEXT: auto result = E::_make();
172172
// CHECK-NEXT: memcpy(result._getOpaquePointer(), &val, sizeof(val));

test/Interop/SwiftToCxx/enums/zero-sized-enum-in-cxx.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
public enum EmptyEnum {}
66
public enum SingleCaseEnum { case first }
77

8-
// CHECK: namespace Enums {
8+
// CHECK: namespace Enums __attribute__((swift_private)) {
99
// CHECK-NOT: class EmptyEnum final {
1010
// CHECK-NOT: class SingleCaseEnum final {
1111
// CHECK: } // namespace Enums

test/Interop/SwiftToCxx/functions/cdecl.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
// RUN: %check-interop-cxx-header-in-clang(%t/cdecl.h)
66

7-
// CHECK-LABEL: namespace CdeclFunctions {
7+
// CHECK-LABEL: namespace CdeclFunctions __attribute__((swift_private)) {
88

99
// CHECK: namespace _impl {
1010
// CHECK: SWIFT_EXTERN int cfuncPassTwo(int x, int y) SWIFT_NOEXCEPT;

test/Interop/SwiftToCxx/functions/function-availability.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
// RUN: %check-interop-cxx-header-in-clang(%t/functions.h)
66

7-
// CHECK-LABEL: namespace Functions {
7+
// CHECK-LABEL: namespace Functions __attribute__((swift_private)) {
88

99
// CHECK-LABEL: namespace _impl {
1010

test/Interop/SwiftToCxx/functions/swift-functions-errors.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
// RUN: %check-interop-cxx-header-in-clang(%t/functions.h)
66

7-
// CHECK-LABEL: namespace Functions {
7+
// CHECK-LABEL: namespace Functions __attribute__((swift_private)) {
88

99
// CHECK-LABEL: namespace _impl {
1010

test/Interop/SwiftToCxx/functions/swift-functions.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
// RUN: %check-interop-cxx-header-in-clang(%t/functions.h)
66

7-
// CHECK-LABEL: namespace Functions {
7+
// CHECK-LABEL: namespace Functions __attribute__((swift_private)) {
88

99
// CHECK-LABEL: namespace _impl {
1010

test/Interop/SwiftToCxx/functions/swift-no-expose-unsupported-alwaysEmitInClient-func.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
// CHECK-NOT: SWIFT_EXTERN bool $s9Functions24alwaysEmitIntoClientFuncyS2bF(bool x) SWIFT_NOEXCEPT SWIFT_CALL; // alwaysEmitIntoClientFunc(_:)
88

9-
// CHECK: namespace Functions {
9+
// CHECK: namespace Functions __attribute__((swift_private)) {
1010
// CHECK-EMPTY:
1111
// CHECK-EMPTY:
1212
// CHECK-EMPTY:

test/Interop/SwiftToCxx/functions/swift-no-expose-unsupported-async-func.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
// CHECK-NOT: SWIFT_EXTERN double $s9Functions9asyncFuncyS2dYaF(double x) SWIFT_NOEXCEPT SWIFT_CALL; // asyncFunc(_:)
88

9-
// CHECK: namespace Functions {
9+
// CHECK: namespace Functions __attribute__((swift_private)) {
1010
// CHECK-EMPTY:
1111
// CHECK-EMPTY:
1212
// CHECK-NEXT: } // namespace Functions

test/Interop/SwiftToCxx/generics/generic-type-traits-fwd.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public struct LaterGeneric<T> {
3939
// CHECK: class ComesFirstEnum final {
4040
// CHECK: LaterGeneric<ComesFirstEnum> returnsLaterOpt() const;
4141

42-
// CHECK: namespace Generics {
42+
// CHECK: namespace Generics __attribute__((swift_private)) {
4343
// CHECK-EMPTY:
4444
// CHECK-NEXT: namespace _impl {
4545
// CHECK-EMPTY:

test/Interop/SwiftToCxx/module/module-to-namespace.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44

55
// RUN: %check-interop-cxx-header-in-clang(%t/empty.h)
66

7-
// CHECK-LABEL: namespace Test {
7+
// CHECK-LABEL: namespace Test __attribute__((swift_private)) {
88
// CHECK: } // namespace Test

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ public func test() -> String {
1414
return ""
1515
}
1616

17-
// CHECK: namespace Swift {
17+
// CHECK: namespace Swift __attribute__((swift_private)) {
1818
// CHECK: class String final {

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
// FIXME: remove need for -Wno-shadow
88

9-
// CHECK: namespace Swift {
9+
// CHECK: namespace Swift __attribute__((swift_private)) {
1010

1111
// CHECK: template<class T_0_0>
1212
// CHECK-NEXT: #ifdef __cpp_concepts

test/Interop/SwiftToCxx/structs/resilient-struct-in-cxx.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public struct FirstSmallStruct {
9292
// CHECK-NEXT: #pragma clang diagnostic pop
9393
// CHECK-NEXT: } // namespace swift
9494
// CHECK-EMPTY:
95-
// CHECK-NEXT: namespace Structs {
95+
// CHECK-NEXT: namespace Structs __attribute__((swift_private)) {
9696

9797
@frozen public struct FrozenStruct {
9898
private let storedInt: Int32

test/Interop/SwiftToCxx/structs/swift-struct-in-cxx.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
// RUN: %check-interop-cxx-header-in-clang(%t/structs.h -Wno-unused-private-field -Wno-unused-function)
66

7-
// CHECK: namespace Structs {
7+
// CHECK: namespace Structs __attribute__((swift_private)) {
88
// CHECK: namespace _impl {
99

10-
// CHECK: namespace Structs {
10+
// CHECK: namespace Structs __attribute__((swift_private)) {
1111

1212
// CHECK: class StructWithIntField;
1313
// CHECK-NEXT: } // end namespace
@@ -20,7 +20,7 @@
2020
// CHECK-NEXT: #pragma clang diagnostic pop
2121
// CHECK-NEXT: } // namespace swift
2222

23-
// CHECK: namespace Structs {
23+
// CHECK: namespace Structs __attribute__((swift_private)) {
2424

2525
// CHECK: namespace _impl {
2626
// CHECK-EMPTY:
@@ -95,7 +95,7 @@
9595
// CHECK-NEXT: #pragma clang diagnostic pop
9696
// CHECK-NEXT: } // namespace swift
9797
// CHECK-EMPTY:
98-
// CHECK-NEXT: namespace Structs {
98+
// CHECK-NEXT: namespace Structs __attribute__((swift_private)) {
9999

100100
public struct StructWithIntField {
101101
let field: Int64

test/Interop/SwiftToCxx/structs/zero-sized-struct-in-cxx.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// RUN: %target-swift-frontend %s -typecheck -module-name Structs -clang-header-expose-decls=all-public -emit-clang-header-path %t/structs.h
33
// RUN: %FileCheck %s < %t/structs.h
44

5-
// CHECK: namespace Structs {
5+
// CHECK: namespace Structs __attribute__((swift_private)) {
66

77
// CHECK-NOT: class ZeroSizedStruct final {
88

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: touch %t/swiftMod.h
5+
// RUN: %target-swift-frontend -typecheck %t/swiftMod.swift -typecheck -module-name SwiftMod -emit-clang-header-path %t/swiftMod.h -I %t -enable-experimental-cxx-interop
6+
7+
// RUN: %FileCheck %s < %t/swiftMod.h
8+
9+
// RUN: %target-swift-frontend -typecheck %t/swiftMod.swift -typecheck -module-name SwiftMod -emit-clang-header-path %t/swiftMod2.h -I %t -enable-experimental-cxx-interop
10+
11+
// RUN: %check-interop-cxx-header-in-clang(%t/swiftMod2.h -Wno-error)
12+
13+
//--- header.h
14+
#include "swiftMod.h"
15+
16+
//--- module.modulemap
17+
module SwiftToCxxTest {
18+
header "header.h"
19+
requires cplusplus
20+
}
21+
22+
//--- swiftMod.swift
23+
import SwiftToCxxTest
24+
25+
@_expose(Cxx)
26+
public func testFunction() -> String {
27+
let arr = Swift.Array<Int>()
28+
let rng = Swift.SystemRandomNumberGenerator()
29+
return ""
30+
}
31+
32+
// CHECK: namespace Swift __attribute__((swift_private)) {
33+
// CHECK: namespace SwiftMod __attribute__((swift_private)) {
34+
// CHECK-NOT: namespace Swift {

test/PrintAsCxx/empty.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@
103103
// CHECK: } // namespace swift
104104
// CHECK-EMPTY:
105105
// CHECK-NEXT: #endif
106-
// CHECK: namespace empty {
106+
// CHECK: namespace empty __attribute__((swift_private)) {
107107
// CHECK: } // namespace empty
108108
// CHECK: #endif
109109

0 commit comments

Comments
 (0)