Skip to content

Commit 8ec1efd

Browse files
authored
Merge pull request #64996 from hyp/eng/5.9/swift_bridging
[5.9] Macro changes for the swift/bridging header
2 parents e6053b7 + acb5323 commit 8ec1efd

12 files changed

+254
-70
lines changed

include/swift/AST/DiagnosticsClangImporter.def

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ NOTE(record_is_dependent, none, "record '%0' is dependent", (StringRef))
165165
NOTE(record_parent_unimportable, none, "record %0's parent is not importable", (StringRef))
166166
NOTE(reference_passed_by_value, none, "function uses foreign reference type "
167167
"'%0' as a value in %1 types which breaks "
168-
"'import_reference' contract (outlined in "
168+
"'swift_shared_reference' contract (outlined in "
169169
"C++ Interop User Manual).",
170170
(StringRef, StringRef))
171171
NOTE(record_not_automatically_importable, none, "record '%0' is not "
@@ -186,11 +186,11 @@ NOTE(projection_reference_not_imported, none, "C++ method '%0' that returns a re
186186
NOTE(projection_may_return_interior_ptr, none, "C++ method '%0' may return an "
187187
"interior pointer. ",
188188
(StringRef))
189-
NOTE(mark_self_contained, none, "Mark type '%0' as 'SELF_CONTAINED' in C++ to "
189+
NOTE(mark_self_contained, none, "Mark type '%0' as 'SWIFT_SELF_CONTAINED' in C++ to "
190190
"make methods that use it available in Swift. ",
191191
(StringRef))
192-
NOTE(mark_safe_to_import, none, "Mark method '%0' as 'SAFE_TO_IMPORT' in C++ to "
193-
"make it available in Swift. ",
192+
NOTE(mark_safe_to_import, none, "annotate method '%0' with 'SWIFT_RETURNS_INDEPENDENT_VALUE' in C++ to "
193+
"make it available in Swift",
194194
(StringRef))
195195

196196
NOTE(at_to_subscript, none, "Do you want to replace it with a call "

lib/ClangImporter/CMakeLists.txt

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,23 @@ add_dependencies(swiftClangImporter
4343

4444
set_swift_llvm_is_available(swiftClangImporter)
4545

46-
# Mark - copy "swift-interop-support.h" into the local include directory and install it
47-
# into the compiler toolchain.
46+
# Mark - copy "bridging" (support header) into the local include directory and
47+
# install it into the compiler toolchain.
4848
set(SWIFTINC_DIR
4949
"${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/include/swift")
5050

5151
add_custom_command(
52-
OUTPUT "${SWIFTINC_DIR}/swift-interop-support.h"
53-
COMMAND "${CMAKE_COMMAND}" "-E" "copy" "${CMAKE_CURRENT_SOURCE_DIR}/swift-interop-support.h" "${SWIFTINC_DIR}")
52+
OUTPUT "${SWIFTINC_DIR}/bridging"
53+
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/bridging"
54+
COMMAND "${CMAKE_COMMAND}" "-E" "copy" "${CMAKE_CURRENT_SOURCE_DIR}/bridging" "${SWIFTINC_DIR}")
5455

5556
add_custom_target("copy_cxxInterop_support_header"
56-
DEPENDS "${SWIFTINC_DIR}/swift-interop-support.h"
57+
DEPENDS "${SWIFTINC_DIR}/bridging"
5758
COMMENT "Copying C++ interop support header to ${SWIFTINC_DIR}")
5859

59-
swift_install_in_component(FILES "${CMAKE_CURRENT_SOURCE_DIR}/swift-interop-support.h"
60+
swift_install_in_component(FILES
61+
"${CMAKE_CURRENT_SOURCE_DIR}/bridging"
62+
"${CMAKE_CURRENT_SOURCE_DIR}/module.modulemap"
6063
DESTINATION "include/swift"
6164
COMPONENT compiler)
6265

lib/ClangImporter/ClangImporter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4408,8 +4408,8 @@ static void diagnoseForeignReferenceTypeFixit(ClangImporter::Implementation &Imp
44084408
HeaderLoc loc, Diagnostic diag) {
44094409
auto importedLoc =
44104410
Impl.SwiftContext.getClangModuleLoader()->importSourceLocation(loc.clangLoc);
4411-
Impl.diagnose(loc, diag)
4412-
.fixItInsert(importedLoc, "SWIFT_REFERENCE_TYPE(<#retain#>, <#release#>) ");
4411+
Impl.diagnose(loc, diag).fixItInsert(
4412+
importedLoc, "SWIFT_SHARED_REFERENCE(<#retain#>, <#release#>) ");
44134413
}
44144414

44154415
bool ClangImporter::Implementation::emitDiagnosticsForTarget(

lib/ClangImporter/bridging

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
//===------------------ bridging - C++ and Swift Interop --------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 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+
// This file provides common utilities and annotations that are useful for C++
14+
// codebases that interoperate with Swift.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
#ifndef SWIFT_CLANGIMPORTER_SWIFT_INTEROP_SUPPORT_H
18+
#define SWIFT_CLANGIMPORTER_SWIFT_INTEROP_SUPPORT_H
19+
20+
/// Specifies that a C++ `class` or `struct` owns and controls the lifetime of all
21+
/// of the objects it references. Such type should not reference any objects whose
22+
/// lifetime is controlled externally. This annotation allows Swift to import methods
23+
/// that return a `class` or `struct` type that is annotated with this macro.
24+
#define SWIFT_SELF_CONTAINED __attribute__((swift_attr("import_owned")))
25+
26+
/// Specifies that a C++ method returns a value that is presumed to contain
27+
/// objects whose lifetime is not dependent on `this` or other parameters passed
28+
/// to the method.
29+
#define SWIFT_RETURNS_INDEPENDENT_VALUE __attribute__((swift_attr("import_unsafe")))
30+
31+
#define _CXX_INTEROP_STRINGIFY(_x) #_x
32+
33+
/// Specifies that a C++ `class` or `struct` is reference-counted using
34+
/// the given `retain` and `release` functions. This annotation lets Swift import
35+
/// such a type as reference counted type in Swift, taking advantage of Swift's
36+
/// automatic reference counting.
37+
///
38+
/// This example shows how to use this macro to let Swift know that
39+
/// a non-copyable reference counted C++ class can be imported as a reference counted type in Swift:
40+
/// ```c++
41+
/// class SWIFT_SHARED_REFERENCE(retainSharedObject, releaseSharedObject)
42+
/// SharedObject : NonCopyable, IntrusiveReferenceCounted<SharedObject> {
43+
/// public:
44+
/// static SharedObject* create();
45+
/// void doSomething();
46+
/// };
47+
///
48+
/// void retainSharedObject(SharedObject *);
49+
/// void releaseSharedObject(SharedObject *);
50+
/// ```
51+
///
52+
/// Then, the Swift programmer would be able to use it in the following manner:
53+
///
54+
/// ```swift
55+
/// let object = SharedObject.create()
56+
/// object.doSomething()
57+
/// // The Swift compiler will release object here.
58+
/// ```
59+
#define SWIFT_SHARED_REFERENCE(_retain, _release) \
60+
__attribute__((swift_attr("import_reference"))) \
61+
__attribute__((swift_attr(_CXX_INTEROP_STRINGIFY(retain:_retain)))) \
62+
__attribute__((swift_attr(_CXX_INTEROP_STRINGIFY(release:_release))))
63+
64+
/// Specifies that a C++ `class` or `struct` is a reference type whose lifetime
65+
/// is presumed to be immortal, i.e. the reference to such object is presumed to
66+
/// always be valid. This annotation lets Swift import such a type as a reference
67+
/// type in Swift.
68+
////
69+
/// This example shows how to use this macro to let Swift know that
70+
/// a non-copyable singleton C++ class can be imported as a reference type in Swift:
71+
/// ```c++
72+
/// class SWIFT_IMMORTAL_REFERENCE
73+
/// LoggerSingleton : NonCopyable {
74+
/// public:
75+
/// static LoggerSingleton &getInstance();
76+
/// void log(int x);
77+
/// };
78+
/// ```
79+
///
80+
/// Then, the Swift programmer would be able to use it in the following manner:
81+
///
82+
/// ```swift
83+
/// let logger = LoggerSingleton.getInstance()
84+
/// logger.log(123)
85+
/// ```
86+
#define SWIFT_IMMORTAL_REFERENCE \
87+
__attribute__((swift_attr("import_reference"))) \
88+
__attribute__((swift_attr(_CXX_INTEROP_STRINGIFY(retain:immortal)))) \
89+
__attribute__((swift_attr(_CXX_INTEROP_STRINGIFY(release:immortal))))
90+
91+
/// Specifies that a C++ `class` or `struct` is a reference type whose lifetime
92+
/// is not managed automatically. The programmer must validate that any reference
93+
/// to such object is valid themselves. This annotation lets Swift import such a type as a reference type in Swift.
94+
#define SWIFT_UNSAFE_REFERENCE \
95+
__attribute__((swift_attr("import_reference"))) \
96+
__attribute__((swift_attr(_CXX_INTEROP_STRINGIFY(retain:immortal)))) \
97+
__attribute__((swift_attr(_CXX_INTEROP_STRINGIFY(release:immortal))))
98+
99+
/// Specifies a name that will be used in Swift for this declaration instead of its original name.
100+
#define SWIFT_NAME(_name) __attribute__((swift_name(#_name)))
101+
102+
/// Specifies that a specific C++ `class` or `struct` conforms to a
103+
/// a specific Swift protocol.
104+
///
105+
/// This example shows how to use this macro to conform a class template to a Swift protocol:
106+
/// ```
107+
/// template<class T>
108+
/// class SWIFT_CONFORMS_TO_PROTOCOL(SwiftModule.ProtocolName)
109+
/// CustomClass {};
110+
/// ```
111+
#define SWIFT_CONFORMS_TO_PROTOCOL(_moduleName_protocolName) \
112+
__attribute__((swift_attr(_CXX_INTEROP_STRINGIFY(conforms_to:_moduleName_protocolName))))
113+
114+
#endif // SWIFT_CLANGIMPORTER_SWIFT_INTEROP_SUPPORT_H

lib/ClangImporter/module.modulemap

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//===------------------ module.modulemap - C++ and Swift module -*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2023 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+
module SwiftBridging {
14+
header "bridging"
15+
16+
export *
17+
}

lib/ClangImporter/swift-interop-support.h

Lines changed: 0 additions & 34 deletions
This file was deleted.

lib/Sema/CSDiagnostics.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4035,8 +4035,7 @@ void MissingMemberFailure::diagnoseUnsafeCxxMethod(SourceLoc loc,
40354035
ctx.Diags
40364036
.diagnose(methodSwiftLoc, diag::mark_safe_to_import,
40374037
name.getBaseIdentifier().str())
4038-
.fixItInsert(methodSwiftLoc,
4039-
" SAFE_TO_IMPORT ");
4038+
.fixItInsert(methodSwiftLoc, " SWIFT_RETURNS_INDEPENDENT_VALUE ");
40404039
} else if (cxxMethod->getReturnType()->isReferenceType()) {
40414040
// Rewrite a call to .at(42) as a subscript.
40424041
if (name.getBaseIdentifier().is("at") &&
@@ -4066,8 +4065,7 @@ void MissingMemberFailure::diagnoseUnsafeCxxMethod(SourceLoc loc,
40664065
ctx.Diags
40674066
.diagnose(methodSwiftLoc, diag::mark_safe_to_import,
40684067
name.getBaseIdentifier().str())
4069-
.fixItInsert(methodSwiftLoc,
4070-
" SAFE_TO_IMPORT ");
4068+
.fixItInsert(methodSwiftLoc, " SWIFT_RETURNS_INDEPENDENT_VALUE ");
40714069
}
40724070
} else if (cxxMethod->getReturnType()->isRecordType()) {
40734071
if (auto cxxRecord = dyn_cast<clang::CXXRecordDecl>(
@@ -4092,12 +4090,10 @@ void MissingMemberFailure::diagnoseUnsafeCxxMethod(SourceLoc loc,
40924090
ctx.Diags
40934091
.diagnose(methodSwiftLoc, diag::mark_safe_to_import,
40944092
name.getBaseIdentifier().str())
4095-
.fixItInsert(methodSwiftLoc,
4096-
" SAFE_TO_IMPORT ");
4093+
.fixItInsert(methodSwiftLoc, " SWIFT_RETURNS_INDEPENDENT_VALUE ");
40974094
ctx.Diags
40984095
.diagnose(baseSwiftLoc, diag::mark_self_contained, returnTypeStr)
4099-
.fixItInsert(baseSwiftLoc,
4100-
"SELF_CONTAINED ");
4096+
.fixItInsert(baseSwiftLoc, "SWIFT_SELF_CONTAINED ");
41014097
}
41024098
}
41034099
}

test/Interop/Cxx/class/fixit-add-safe-to-import-self-contained.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,21 @@ struct X {
2121
import Test
2222

2323
public func test(x: X) {
24-
// CHECK: note: Mark method 'test' as 'SAFE_TO_IMPORT' in C++ to make it available in Swift.
24+
// CHECK: note: annotate method 'test' with 'SWIFT_RETURNS_INDEPENDENT_VALUE' in C++ to make it available in Swift
2525
// CHECK: int *test() { }
2626
// CHECK: ^
27-
// CHECK: SAFE_TO_IMPORT
27+
// CHECK: SWIFT_RETURNS_INDEPENDENT_VALUE
2828

2929
x.test()
3030

31-
// CHECK: note: Mark method 'other' as 'SAFE_TO_IMPORT' in C++ to make it available in Swift.
31+
// CHECK: note: annotate method 'other' with 'SWIFT_RETURNS_INDEPENDENT_VALUE' in C++ to make it available in Swift
3232
// CHECK: Ptr other() { }
3333
// CHECK: ^
34-
// CHECK: SAFE_TO_IMPORT
34+
// CHECK: SWIFT_RETURNS_INDEPENDENT_VALUE
3535

36-
// CHECK: note: Mark type 'Ptr' as 'SELF_CONTAINED' in C++ to make methods that use it available in Swift.
36+
// CHECK: note: Mark type 'Ptr' as 'SWIFT_SELF_CONTAINED' in C++ to make methods that use it available in Swift.
3737
// CHECK: struct Ptr {
3838
// CHECK: ^
39-
// CHECK: SELF_CONTAINED
39+
// CHECK: SWIFT_SELF_CONTAINED
4040
x.other()
4141
}

test/Interop/Cxx/class/invalid-class-errors.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ import Test
3030
// CHECK: note: record 'A' is not automatically available: does not have a copy constructor or destructor. Does this type have reference semantics?
3131
// CHECK: struct A {
3232
// CHECK: ^
33-
// CHECK: SWIFT_REFERENCE_TYPE(<#retain#>, <#release#>)
33+
// CHECK: SWIFT_SHARED_REFERENCE(<#retain#>, <#release#>)
3434
public func test(x: A) { }
3535
// CHECK: note: record 'B' is not automatically available: does not have a copy constructor or destructor. Does this type have reference semantics?
3636
// CHECK: struct {{.*}}B {
3737
// CHECK: ^
38-
// CHECK: SWIFT_REFERENCE_TYPE(<#retain#>, <#release#>)
38+
// CHECK: SWIFT_SHARED_REFERENCE(<#retain#>, <#release#>)
3939
public func test(x: B) { }
4040
// CHECK: note: record 'Nested' is not automatically available: does not have a copy constructor or destructor. Does this type have reference semantics?
4141
// CHECK: struct Nested {
4242
// CHECK: ^
43-
// CHECK: SWIFT_REFERENCE_TYPE(<#retain#>, <#release#>)
43+
// CHECK: SWIFT_SHARED_REFERENCE(<#retain#>, <#release#>)
4444
public func test(x: Namespace.Nested) { }

test/Interop/Cxx/class/invalid-unsafe-projection-errors.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,16 @@ import Test
2929
public func test(x: M) {
3030
// CHECK: note: C++ method 'test1' that returns a pointer of type 'UnsafeMutablePointer' is unavailable.
3131
// CHECK: note: C++ method 'test1' may return an interior pointer.
32-
// CHECK: note: Mark method 'test1' as 'SAFE_TO_IMPORT' in C++ to make it available in Swift.
32+
// CHECK: note: annotate method 'test1' with 'SWIFT_RETURNS_INDEPENDENT_VALUE' in C++ to make it available in Swift
3333
x.test1()
3434
// CHECK: note: C++ method 'test2' that returns a reference of type 'UnsafeMutablePointer' is unavailable.
3535
// CHECK: note: C++ method 'test2' may return an interior pointer.
36-
// CHECK: note: Mark method 'test2' as 'SAFE_TO_IMPORT' in C++ to make it available in Swift.
36+
// CHECK: note: annotate method 'test2' with 'SWIFT_RETURNS_INDEPENDENT_VALUE' in C++ to make it available in Swift
3737
x.test2()
3838
// CHECK: note: C++ method 'test3' that returns a value of type 'Ptr' is unavailable.
3939
// CHECK: note: C++ method 'test3' may return an interior pointer.
40-
// CHECK: note: Mark method 'test3' as 'SAFE_TO_IMPORT' in C++ to make it available in Swift.
41-
// CHECK: note: Mark type 'Ptr' as 'SELF_CONTAINED' in C++ to make methods that use it available in Swift.
40+
// CHECK: note: annotate method 'test3' with 'SWIFT_RETURNS_INDEPENDENT_VALUE' in C++ to make it available in Swift
41+
// CHECK: note: Mark type 'Ptr' as 'SWIFT_SELF_CONTAINED' in C++ to make methods that use it available in Swift.
4242
x.test3()
4343
// CHECK: note: C++ method 'begin' that returns an iterator is unavailable
4444
// CHECK: note: C++ methods that return iterators are potentially unsafe. Try re-writing to use Swift iterator APIs.

0 commit comments

Comments
 (0)