Skip to content

Commit 54efb01

Browse files
authored
Merge pull request #76209 from swiftlang/gaborh/nonescapable-attr
[cxx-interop] Add a SWIFT_NONESCAPABLE attribute to the bridging header
2 parents 9cf115a + 738b4c6 commit 54efb01

File tree

5 files changed

+46
-2
lines changed

5 files changed

+46
-2
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7370,6 +7370,10 @@ static bool hasNonCopyableAttr(const clang::RecordDecl *decl) {
73707370
return hasSwiftAttribute(decl, "~Copyable");
73717371
}
73727372

7373+
bool importer::hasNonEscapableAttr(const clang::RecordDecl *decl) {
7374+
return hasSwiftAttribute(decl, "~Escapable");
7375+
}
7376+
73737377
/// Recursively checks that there are no pointers in any fields or base classes.
73747378
/// Does not check C++ records with specific API annotations.
73757379
static bool hasPointerInSubobjects(const clang::CXXRecordDecl *decl) {

lib/ClangImporter/ImportDecl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2201,6 +2201,12 @@ namespace {
22012201
MoveOnlyAttr(/*Implicit=*/true));
22022202
}
22032203

2204+
if (Impl.SwiftContext.LangOpts.hasFeature(Feature::NonescapableTypes) &&
2205+
importer::hasNonEscapableAttr(decl)) {
2206+
result->getAttrs().add(new (Impl.SwiftContext)
2207+
NonEscapableAttr(/*Implicit=*/true));
2208+
}
2209+
22042210
// FIXME: Figure out what to do with superclasses in C++. One possible
22052211
// solution would be to turn them into members and add conversion
22062212
// functions.

lib/ClangImporter/ImporterImpl.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2029,9 +2029,11 @@ inline std::string getPrivateOperatorName(const std::string &OperatorToken) {
20292029

20302030
bool hasUnsafeAPIAttr(const clang::Decl *decl);
20312031

2032+
bool hasNonEscapableAttr(const clang::RecordDecl *decl);
2033+
20322034
bool isViewType(const clang::CXXRecordDecl *decl);
20332035

2034-
}
2035-
}
2036+
} // end namespace importer
2037+
} // end namespace swift
20362038

20372039
#endif

lib/ClangImporter/SwiftBridging/swift/bridging

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,12 @@
158158
#define SWIFT_NONCOPYABLE \
159159
__attribute__((swift_attr("~Copyable")))
160160

161+
/// Specifies that a specific c++ type such class or struct should be imported
162+
/// as a non-escapable Swift value type when the non-escapable language feature
163+
/// is enabled.
164+
#define SWIFT_NONESCAPABLE \
165+
__attribute__((swift_attr("~Escapable")))
166+
161167
#else // #if _CXX_INTEROP_HAS_ATTRIBUTE(swift_attr)
162168

163169
// Empty defines for compilers that don't support `attribute(swift_attr)`.
@@ -172,6 +178,7 @@
172178
#define SWIFT_MUTATING
173179
#define SWIFT_UNCHECKED_SENDABLE
174180
#define SWIFT_NONCOPYABLE
181+
#define SWIFT_NONESCAPABLE
175182

176183
#endif // #if _CXX_INTEROP_HAS_ATTRIBUTE(swift_attr)
177184

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: rm -rf %t
2+
// RUN: split-file %s %t
3+
// RUN: not %target-swift-frontend -typecheck -I %swift_src_root/lib/ClangImporter/SwiftBridging -I %t/Inputs %t/test.swift -enable-experimental-feature NonescapableTypes -cxx-interoperability-mode=default -diagnostic-style llvm 2>&1 | %FileCheck %s
4+
5+
//--- Inputs/module.modulemap
6+
module Test {
7+
header "nonescapable.h"
8+
requires cplusplus
9+
}
10+
11+
//--- Inputs/nonescapable.h
12+
#include "swift/bridging"
13+
14+
struct SWIFT_NONESCAPABLE A {
15+
int a;
16+
};
17+
18+
//--- test.swift
19+
20+
import Test
21+
22+
// CHECK: error: cannot infer lifetime dependence, no parameters found that are either ~Escapable or Escapable with a borrowing ownership
23+
public func test() -> A {
24+
A()
25+
}

0 commit comments

Comments
 (0)