Skip to content

Commit 69a9149

Browse files
committed
[interop] update names and add docs for the interop C++ helper macros
1 parent 8fd028c commit 69a9149

File tree

1 file changed

+86
-6
lines changed

1 file changed

+86
-6
lines changed

lib/ClangImporter/bridging

Lines changed: 86 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,98 @@
1717
#ifndef SWIFT_CLANGIMPORTER_SWIFT_INTEROP_SUPPORT_H
1818
#define SWIFT_CLANGIMPORTER_SWIFT_INTEROP_SUPPORT_H
1919

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.
2024
#define SELF_CONTAINED __attribute__((swift_attr("import_owned")))
21-
#define SAFE_TO_IMPORT __attribute__((swift_attr("import_unsafe")))
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 RETURNS_INDEPENDENT_VALUE __attribute__((swift_attr("import_unsafe")))
2230

2331
#define _CXX_INTEROP_STRINGIFY(_x) #_x
24-
#define SWIFT_REFERENCE_TYPE(_retain, _release) \
25-
__attribute__((swift_attr("import_reference"))) \
26-
__attribute__((swift_attr(_CXX_INTEROP_STRINGIFY(retain:_retain)))) \
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 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 SHARED_REFERENCE(_retain, _release) \
60+
__attribute__((swift_attr("import_reference"))) \
61+
__attribute__((swift_attr(_CXX_INTEROP_STRINGIFY(retain:_retain)))) \
2762
__attribute__((swift_attr(_CXX_INTEROP_STRINGIFY(release:_release))))
2863

64+
/// Specifies that a C++ `class` or `struct` is a reference type whose lifetime
65+
/// is presumed to me 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 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 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 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.
29100
#define SWIFT_NAME(_name) __attribute__((swift_name(#_name)))
30101

31-
#define CONFORMS_TO(_name) \
32-
__attribute__((swift_attr(_CXX_INTEROP_STRINGIFY(conforms_to:_name))))
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 CONFORMS_TO_PROTOCOL(SwiftModule.ProtocolName)
109+
/// CustomClass {};
110+
/// ```
111+
#define CONFORMS_TO_PROTOCOL(_moduleName_protocolName) \
112+
__attribute__((swift_attr(_CXX_INTEROP_STRINGIFY(conforms_to:_moduleName_protocolName))))
33113

34114
#endif // SWIFT_CLANGIMPORTER_SWIFT_INTEROP_SUPPORT_H

0 commit comments

Comments
 (0)