450 lines · plain
1================================================2API Notes: Annotations Without Modifying Headers3================================================4 5**The Problem:** You have headers you want to use, but you also want to add6extra information to the API. You don't want to put that information in the7headers themselves --- perhaps because you want to keep them clean for other8clients, or perhaps because they're from some open source project and you don't9want to modify them at all.10 11**Incomplete solution:** Redeclare all the interesting parts of the API in your12own header and add the attributes you want. Unfortunately, this:13 14* doesn't work with attributes that must be present on a definition15* doesn't allow changing the definition in other ways16* requires your header to be included in any client code to take effect17 18**Better solution:** Provide a "sidecar" file with the information you want to19add, and have that automatically get picked up by the module-building logic in20the compiler.21 22That's API notes.23 24API notes use a YAML-based file format. YAML is a format best explained by25example, so here is a `small example26<https://github.com/llvm/llvm-project/blob/main/clang/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.apinotes>`_27from the compiler test suite of API28notes for a hypothetical "SomeKit" framework.29 30 31Usage32=====33 34API notes files are found relative to the module map that defines a module,35under the name "SomeKit.apinotes" for a module named "SomeKit". Additionally, a36file named "SomeKit_private.apinotes" will also be picked up to go with a37private module map. For bare modules these two files will be in the same38directory as the corresponding module map; for framework modules, they should39be placed in the Headers and PrivateHeaders directories, respectively. The40module map for a private top-level framework module should be placed in the41PrivateHeaders directory as well, though it does not need an additional42"_private" suffix on its name.43 44Clang will search for API notes files next to module maps only when passed the45``-fapinotes-modules`` option.46 47 48Limitations49===========50 51- Since they're identified by module name, API notes cannot be used to modify52 arbitrary textual headers.53 54 55"Versioned" API Notes56=====================57 58Many API notes affect how a C API is imported into Swift. In order to change59that behavior while still remaining backwards-compatible, API notes can be60selectively applied based on the Swift compatibility version provided to the61compiler (e.g. ``-fapi-notes-swift-version=5``). The rule is that an62explicitly-versioned API note applies to that version *and all earlier63versions,* and any applicable explicitly-versioned API note takes precedence64over an unversioned API note.65 66 67Reference68=========69 70An API notes file contains a YAML dictionary with the following top-level71entries:72 73:Name:74 75 The name of the module (the framework name, for frameworks). Note that this76 is always the name of a top-level module, even within a private API notes77 file.78 79 ::80 81 Name: MyFramework82 83:Classes, Protocols, Tags, Typedefs, Globals, Enumerators, Functions, Namespaces:84 85 Arrays of top-level declarations. Each entry in the array must have a86 'Name' key with its Objective-C or C++ name. "Tags" refers to structs,87 C++ classes, enums, and unions; "Classes" refers to Objective-C classes;88 "Enumerators" refers to enum cases.89 90 ::91 92 Classes:93 - Name: MyController94 …95 - Name: MyView96 …97 98:SwiftVersions:99 100 Contains explicit information for backwards compatibility. Each entry in101 the array contains a 'Version' key, which should be set to '4' for102 annotations that only apply to Swift 4 mode and earlier. The other entries103 in this dictionary are the same declaration entries as at the top level:104 Classes, Protocols, Tags, Typedefs, Globals, Enumerators, and Functions.105 106 ::107 108 SwiftVersions:109 - Version: 4110 Classes: …111 Protocols: …112 113Each entry under 'Classes' and 'Protocols' can contain "Methods" and114"Properties" arrays, in addition to the attributes described below:115 116:Methods:117 118 Identified by 'Selector' and 'MethodKind'; the MethodKind is either119 "Instance" or "Class".120 121 ::122 123 Classes:124 - Name: UIViewController125 Methods:126 - Selector: "presentViewController:animated:"127 MethodKind: Instance128 …129 130:Properties:131 132 Identified by 'Name' and 'PropertyKind'; the PropertyKind is also either133 "Instance" or "Class".134 135 ::136 137 Classes:138 - Name: UIView139 Properties:140 - Name: subviews141 PropertyKind: Instance142 …143 144Each declaration supports the following annotations (if relevant to that145declaration kind), all of which are optional:146 147:SwiftName:148 149 Equivalent to ``NS_SWIFT_NAME``. For a method, must include the full Swift name150 with all arguments. Use "_" to omit an argument label.151 152 ::153 154 - Selector: "presentViewController:animated:"155 MethodKind: Instance156 SwiftName: "present(_:animated:)"157 158 - Class: NSBundle159 SwiftName: Bundle160 161:SwiftImportAs:162 163 For a class, possible values are ``owned`` (equivalent to164 ``SWIFT_SELF_CONTAINED``) or ``reference`` (equivalent to165 ``SWIFT_SHARED_REFERENCE``, also requires specifying ``SwiftReleaseOp`` and166 ``SwiftRetainOp``).167 168 For a method, possible values are ``unsafe`` (equivalent169 to ``SWIFT_RETURNS_INDEPENDENT_VALUE``) or ``computed_property`` (equivalent to170 ``SWIFT_COMPUTED_PROPERTY``).171 172 ::173 174 Tags:175 - Name: OwnedStorage176 SwiftImportAs: owned177 178:SwiftRetainOp, SwiftReleaseOp:179 180 Controls the lifetime operations of a class which uses custom reference181 counting. The class must be annotated as a reference type using182 ``SwiftImportAs: reference``. The values are either names of global functions,183 each taking a single parameter of a pointer type, or ``immortal`` for a type184 that is considered alive for the duration of the program.185 186 ::187 188 Tags:189 - Name: RefCountedStorage190 SwiftImportAs: reference191 SwiftReleaseOp: RCRelease192 SwiftRetainOp: RCRetain193 - Name: ImmortalSingleton194 SwiftImportAs: reference195 SwiftReleaseOp: immortal196 SwiftRetainOp: immortal197 198:SwiftCopyable:199 200 Allows annotating a C++ class as non-copyable in Swift. Equivalent to201 ``SWIFT_NONCOPYABLE``, or to an explicit conformance ``: ~Copyable``.202 203 ::204 205 Tags:206 - Name: tzdb207 SwiftCopyable: false208 209 A non-copyable type can have a "destroy" operation, specified with210 `SwiftDestroyOp`, which will be invoked on the instance when it is no211 longer in use to free up resources.212 213 ::214 215 Tags:216 - Name: WGPUAdapterInfo217 SwiftCopyable: false218 SwiftDestroyOp: wgpuAdapterInfoFreeMembers219 220:SwiftConformsTo:221 222 Allows annotating a C++ class as conforming to a Swift protocol. Equivalent223 to ``SWIFT_CONFORMS_TO_PROTOCOL``. The value is a module-qualified name of a224 Swift protocol.225 226 ::227 228 Tags:229 - Name: vector230 SwiftConformsTo: Cxx.CxxSequence231 232:SwiftSafety:233 234 Import a declaration as ``@safe`` or ``@unsafe`` to Swift.235 236 ::237 238 Tags:239 - Name: UnsafeType240 SwiftSafety: unsafe241 - Name: span242 Methods:243 - Name: size244 SwiftSafety: safe245 246:Availability, AvailabilityMsg:247 248 A value of "nonswift" is equivalent to ``NS_SWIFT_UNAVAILABLE``. A value of249 "available" can be used in the "SwiftVersions" section to undo the effect of250 "nonswift".251 252 ::253 254 - Selector: "dealloc"255 MethodKind: Instance256 Availability: nonswift257 AvailabilityMsg: "prefer 'deinit'"258 259:SwiftPrivate:260 261 Equivalent to NS_REFINED_FOR_SWIFT.262 263 ::264 265 - Name: CGColorEqualToColor266 SwiftPrivate: true267 268:Nullability:269 270 Used for properties and globals. There are four options, identified by their271 initials:272 273 - ``Nonnull`` or ``N`` (corresponding to ``_Nonnull``)274 - ``Optional`` or ``O`` (corresponding to ``_Nullable``)275 - ``Unspecified`` or ``U`` (corresponding to ``_Null_unspecified``)276 - ``Scalar`` or ``S`` (deprecated)277 278 Note that 'Nullability' is overridden by 'Type', even in a "SwiftVersions"279 section.280 281 .. note::282 283 'Nullability' can also be used to describe the argument types of methods284 and functions, but this usage is deprecated in favor of 'Parameters' (see285 below).286 287 ::288 289 - Name: dataSource290 Nullability: O291 292:NullabilityOfRet:293 294 Used for methods and functions. Describes the nullability of the return type.295 296 Note that 'NullabilityOfRet' is overridden by 'ResultType', even in a297 "SwiftVersions" section.298 299 .. warning::300 301 Due to a compiler bug, 'NullabilityOfRet' may change nullability of the302 parameters as well (rdar://30544062). Avoid using it and instead use303 'ResultType' and specify the return type along with a nullability304 annotation (see documentation for 'ResultType').305 306 ::307 308 - Selector: superclass309 MethodKind: Class310 NullabilityOfRet: O311 312:Type:313 314 Used for properties and globals. This completely overrides the type of the315 declaration; it should ideally only be used for Swift backwards316 compatibility, when existing type information has been made more precise in a317 header. Prefer 'Nullability' and other annotations when possible.318 319 We parse the specified type as if it appeared at the location of the320 declaration whose type is being modified. Macros are not available and321 nullability must be applied explicitly (even in an ``NS_ASSUME_NONNULL_BEGIN``322 section).323 324 ::325 326 - Name: delegate327 PropertyKind: Instance328 Type: "id"329 330:ResultType:331 332 Used for methods and functions. This completely overrides the return type; it333 should ideally only be used for Swift backwards compatibility, when existing334 type information has been made more precise in a header.335 336 We parse the specified type as if it appeared at the location of the337 declaration whose type is being modified. Macros are not available and338 nullability must be applied explicitly (even in an ``NS_ASSUME_NONNULL_BEGIN``339 section).340 341 ::342 343 - Selector: "subviews"344 MethodKind: Instance345 ResultType: "NSArray * _Nonnull"346 347:SwiftImportAsAccessors:348 349 Used for properties. If true, the property will be exposed in Swift as its350 accessor methods, rather than as a computed property using ``var``.351 352 ::353 354 - Name: currentContext355 PropertyKind: Class356 SwiftImportAsAccessors: true357 358:NSErrorDomain:359 360 Used for ``NSError`` code enums. The value is the name of the associated361 domain ``NSString`` constant; an empty string (``""``) means the enum is a362 normal enum rather than an error code.363 364 ::365 366 - Name: MKErrorCode367 NSErrorDomain: MKErrorDomain368 369:SwiftWrapper:370 371 Controls ``NS_STRING_ENUM`` and ``NS_EXTENSIBLE_STRING_ENUM``. There are three372 options:373 374 - "struct" (extensible)375 - "enum"376 - "none"377 378 Note that even an "enum" wrapper is still presented as a struct in Swift;379 it's just a "more enum-like" struct.380 381 ::382 383 - Name: AVMediaType384 SwiftWrapper: none385 386:EnumKind:387 388 Has the same effect as ``NS_ENUM`` and ``NS_OPTIONS``. There are four options:389 390 - "NSEnum" / "CFEnum"391 - "NSClosedEnum" / "CFClosedEnum"392 - "NSOptions" / "CFOptions"393 - "none"394 395 ::396 397 - Name: GKPhotoSize398 EnumKind: none399 400:Parameters:401 402 Used for methods and functions. Parameters are identified by a 0-based403 'Position' and support the 'Nullability', 'NoEscape', and 'Type' keys.404 405 .. note::406 407 Using 'Parameters' within a parameter entry to describe the parameters of a408 block is not implemented. Use 'Type' on the entire parameter instead.409 410 ::411 412 - Selector: "isEqual:"413 MethodKind: Instance414 Parameters:415 - Position: 0416 Nullability: O417 418:NoEscape:419 420 Used only for block parameters. Equivalent to ``NS_NOESCAPE``.421 422 ::423 424 - Name: dispatch_sync425 Parameters:426 - Position: 0427 NoEscape: true428 429:SwiftBridge:430 431 Used for Objective-C class types bridged to Swift value types. An empty432 string ("") means a type is not bridged. Not supported outside of Apple433 frameworks (the Swift side of it requires conforming to implementation-detail434 protocols that are subject to change).435 436 ::437 438 - Name: NSIndexSet439 SwiftBridge: IndexSet440 441:DesignatedInit:442 443 Used for init methods. Equivalent to ``NS_DESIGNATED_INITIALIZER``.444 445 ::446 447 - Selector: "initWithFrame:"448 MethodKind: Instance449 DesignatedInit: true450