Skip to content

Commit 5fb34b4

Browse files
authored
Merge pull request #40995 from hyp/function-to-cxx-thunk
[interop][SwiftToC++] print C++ interface for top-level Swift functions
2 parents ca25261 + ebcf2f7 commit 5fb34b4

16 files changed

+551
-92
lines changed

include/swift/AST/SwiftNameTranslation.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,16 @@ namespace objc_translation {
5454
bool checkParent = true);
5555

5656
} // end namespace objc_translation
57+
58+
namespace cxx_translation {
59+
60+
/// Returns true if the given value decl D is visible to C++ of its
61+
/// own accord (i.e. without considering its context)
62+
bool isVisibleToCxx(const ValueDecl *VD, AccessLevel minRequiredAccess,
63+
bool checkParent = true);
64+
65+
} // end namespace cxx_translation
66+
5767
} // end namespace swift
5868

5969
#endif

lib/AST/SwiftNameTranslation.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,20 @@ isVisibleToObjC(const ValueDecl *VD, AccessLevel minRequiredAccess,
150150
}
151151
return false;
152152
}
153+
154+
bool swift::cxx_translation::isVisibleToCxx(const ValueDecl *VD,
155+
AccessLevel minRequiredAccess,
156+
bool checkParent) {
157+
if (VD->isObjC())
158+
return false;
159+
if (VD->getFormalAccess() >= minRequiredAccess) {
160+
return true;
161+
} else if (checkParent) {
162+
if (auto ctor = dyn_cast<ConstructorDecl>(VD)) {
163+
// Check if we're overriding an initializer that is visible to obj-c
164+
if (auto parent = ctor->getOverriddenDecl())
165+
return isVisibleToCxx(parent, minRequiredAccess, false);
166+
}
167+
}
168+
return false;
169+
}

lib/PrintAsClang/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22
add_swift_host_library(swiftPrintAsClang STATIC
3+
CxxSynthesis.cpp
34
DeclAndTypePrinter.cpp
45
ModuleContentsWriter.cpp
56
PrintAsClang.cpp)

lib/PrintAsClang/CxxSynthesis.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//===--- CxxSynthesis.cpp - Rules for synthesizing C++ code -----*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "CxxSynthesis.h"
14+
15+
using namespace swift;
16+
using namespace cxx_synthesis;
17+
18+
StringRef cxx_synthesis::getCxxImplNamespaceName() { return "_impl"; }
19+
20+
/// Print a C++ namespace declaration with the give name and body.
21+
void CxxPrinter::printNamespace(
22+
llvm::function_ref<void(raw_ostream &OS)> namePrinter,
23+
llvm::function_ref<void(raw_ostream &OS)> bodyPrinter) const {
24+
os << "namespace ";
25+
namePrinter(os);
26+
os << " {\n\n";
27+
bodyPrinter(os);
28+
os << "\n} // namespace ";
29+
namePrinter(os);
30+
os << "\n\n";
31+
}
32+
33+
void CxxPrinter::printNamespace(
34+
StringRef name,
35+
llvm::function_ref<void(raw_ostream &OS)> bodyPrinter) const {
36+
printNamespace([&](raw_ostream &os) { os << name; }, bodyPrinter);
37+
}

lib/PrintAsClang/CxxSynthesis.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//===--- CxxSynthesis.h - Rules for synthesizing C++ code -------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_PRINTASCLANG_CXXSYNTHESIS_H
14+
#define SWIFT_PRINTASCLANG_CXXSYNTHESIS_H
15+
16+
#include "swift/Basic/LLVM.h"
17+
#include "llvm/ADT/StringRef.h"
18+
#include "llvm/Support/raw_ostream.h"
19+
20+
namespace swift {
21+
22+
namespace cxx_synthesis {
23+
24+
/// Return the name of the implementation namespace that is used to hide
25+
/// declarations from the namespace that corresponds to the imported Swift
26+
/// module in C++.
27+
StringRef getCxxImplNamespaceName();
28+
29+
class CxxPrinter {
30+
public:
31+
CxxPrinter(raw_ostream &os) : os(os) {}
32+
33+
/// Print a C++ namespace declaration with the give name and body.
34+
void
35+
printNamespace(llvm::function_ref<void(raw_ostream &OS)> namePrinter,
36+
llvm::function_ref<void(raw_ostream &OS)> bodyPrinter) const;
37+
38+
void
39+
printNamespace(StringRef name,
40+
llvm::function_ref<void(raw_ostream &OS)> bodyPrinter) const;
41+
42+
private:
43+
raw_ostream &os;
44+
};
45+
46+
} // end namespace cxx_synthesis
47+
} // end namespace swift
48+
49+
#endif

0 commit comments

Comments
 (0)