Skip to content

Commit fbf7c24

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

File tree

6 files changed

+73
-21
lines changed

6 files changed

+73
-21
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 3 additions & 0 deletions
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

Lines changed: 17 additions & 6 deletions
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

Lines changed: 12 additions & 8 deletions
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

Lines changed: 3 additions & 1 deletion
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

Lines changed: 4 additions & 6 deletions
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
}
Lines changed: 34 additions & 0 deletions
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 {

0 commit comments

Comments
 (0)