This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG85d506400081: docs: add documentation describing API Notes 
(authored by compnerd).

Changed prior to commit:
  https://reviews.llvm.org/D88446?vs=295924&id=296243#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D88446/new/

https://reviews.llvm.org/D88446

Files:
  clang/docs/APINotes.rst
  
clang/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.apinotes
  clang/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.h
  
clang/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKitExplicitNullability.h
  
clang/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit_private.apinotes

Index: clang/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit_private.apinotes
===================================================================
--- /dev/null
+++ clang/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit_private.apinotes
@@ -0,0 +1,15 @@
+Name: SomeKit
+Classes:
+  - Name: A
+    Methods:
+      - Selector: "privateTransform:input:"
+        MethodKind:      Instance
+        NullabilityOfRet: N
+        Nullability:      [ N, S ]
+    Properties:
+      - Name: internalProperty
+        Nullability: N
+Protocols:
+  - Name: InternalProtocol
+    Availability: none
+    AvailabilityMsg: "not for you"
Index: clang/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKitExplicitNullability.h
===================================================================
--- /dev/null
+++ clang/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKitExplicitNullability.h
@@ -0,0 +1,4 @@
+@interface A(ExplicitNullabilityProperties)
+@property (nonatomic, readwrite, retain, nonnull) A *explicitNonnullInstance;
+@property (nonatomic, readwrite, retain, nullable) A *explicitNullableInstance;
+@end
Index: clang/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.h
===================================================================
--- /dev/null
+++ clang/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.h
@@ -0,0 +1,60 @@
+#ifndef SOMEKIT_H
+#define SOMEKIT_H
+
+__attribute__((objc_root_class))
+@interface A
+-(A*)transform:(A*)input;
+-(A*)transform:(A*)input integer:(int)integer;
+
+@property (nonatomic, readonly, retain) A* someA;
+@property (nonatomic, retain) A* someOtherA;
+
+@property (nonatomic) int intValue;
+@end
+
+@interface B : A
+@end
+
+@interface C : A
+- (instancetype)init;
+- (instancetype)initWithA:(A*)a;
+@end
+
+@interface ProcessInfo : A
++(instancetype)processInfo;
+@end
+
+@interface A(NonNullProperties)
+@property (nonatomic, readwrite, retain) A *nonnullAInstance;
+@property (class, nonatomic, readwrite, retain) A *nonnullAInstance;
+
+@property (nonatomic, readwrite, retain) A *nonnullAClass;
+@property (class, nonatomic, readwrite, retain) A *nonnullAClass;
+
+@property (nonatomic, readwrite, retain) A *nonnullABoth;
+@property (class, nonatomic, readwrite, retain) A *nonnullABoth;
+@end
+
+#import <SomeKit/SomeKitExplicitNullability.h>
+
+extern int *global_int_ptr;
+
+int *global_int_fun(int *ptr, int *ptr2);
+
+#define SOMEKIT_DOUBLE double
+
+__attribute__((objc_root_class))
+@interface OverriddenTypes
+-(int *)methodToMangle:(int *)ptr1 second:(int *)ptr2;
+@property int *intPropertyToMangle;
+@end
+
+@interface A(ImplicitGetterSetters)
+@property (nonatomic, readonly, retain) A *implicitGetOnlyInstance;
+@property (class, nonatomic, readonly, retain) A *implicitGetOnlyClass;
+
+@property (nonatomic, readwrite, retain) A *implicitGetSetInstance;
+@property (class, nonatomic, readwrite, retain) A *implicitGetSetClass;
+@end
+
+#endif
Index: clang/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.apinotes
===================================================================
--- /dev/null
+++ clang/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.apinotes
@@ -0,0 +1,98 @@
+Name: SomeKit
+Classes:
+  - Name: A
+    Methods:
+      - Selector:        "transform:"
+        MethodKind:      Instance
+        Availability:    none
+        AvailabilityMsg: "anything but this"
+      - Selector: "transform:integer:"
+        MethodKind:      Instance
+        NullabilityOfRet: N
+        Nullability:      [ N, S ]
+      - Selector: "implicitGetOnlyInstance"
+        MethodKind:      Instance
+        Availability:    none
+        AvailabilityMsg: "getter gone"
+      - Selector: "implicitGetOnlyClass"
+        MethodKind:      Class
+        Availability:    none
+        AvailabilityMsg: "getter gone"
+      - Selector: "implicitGetSetInstance"
+        MethodKind:      Instance
+        Availability:    none
+        AvailabilityMsg: "getter gone"
+      - Selector: "implicitGetSetClass"
+        MethodKind:      Class
+        Availability:    none
+        AvailabilityMsg: "getter gone"
+      - Selector: "setImplicitGetSetInstance:"
+        MethodKind:      Instance
+        Availability:    none
+        AvailabilityMsg: "setter gone"
+      - Selector: "setImplicitGetSetClass:"
+        MethodKind:      Class
+        Availability:    none
+        AvailabilityMsg: "setter gone"
+    Properties:
+      - Name: intValue
+        PropertyKind:    Instance
+        Availability: none
+        AvailabilityMsg: "wouldn't work anyway"
+      - Name: nonnullAInstance
+        PropertyKind:    Instance
+        Nullability:     N
+      - Name: nonnullAClass
+        PropertyKind:    Class
+        Nullability:     N
+      - Name: nonnullABoth
+        Nullability:     N
+  - Name: B
+    Availability: none
+    AvailabilityMsg: "just don't"
+  - Name: C
+    Methods:
+      - Selector: "initWithA:"
+        MethodKind: Instance
+        DesignatedInit: true
+  - Name: OverriddenTypes
+    Methods:
+      - Selector: "methodToMangle:second:"
+        MethodKind: Instance
+        ResultType: 'char *'
+        Parameters:
+          - Position: 0
+            Type: 'SOMEKIT_DOUBLE *'
+          - Position: 1
+            Type: 'float *'
+    Properties:
+      - Name: intPropertyToMangle
+        PropertyKind: Instance
+        Type: 'double *'
+Functions:
+  - Name: global_int_fun
+    ResultType: 'char *'
+    Parameters:
+      - Position: 0
+        Type: 'double *'
+      - Position: 1
+        Type: 'float *'
+Globals:
+  - Name: global_int_ptr
+    Type: 'double (*)(int, int)'
+SwiftVersions:
+  - Version: 3.0
+    Classes:
+      - Name: A
+        Methods:
+          - Selector: "transform:integer:"
+            MethodKind:      Instance
+            NullabilityOfRet: O
+            Nullability:      [ O, S ]
+        Properties:
+          - Name: explicitNonnullInstance
+            PropertyKind:    Instance
+            Nullability:     O
+          - Name: explicitNullableInstance
+            PropertyKind:    Instance
+            Nullability:     N
Index: clang/docs/APINotes.rst
===================================================================
--- /dev/null
+++ clang/docs/APINotes.rst
@@ -0,0 +1,363 @@
+================================================
+API Notes: Annotations Without Modifying Headers
+================================================
+
+**The Problem:** You have headers you want to use, but you also want to add
+extra information to the API. You don't want to put that information in the
+headers themselves --- perhaps because you want to keep them clean for other
+clients, or perhaps because they're from some open source project and you don't
+want to modify them at all.
+
+**Incomplete solution:** Redeclare all the interesting parts of the API in your
+own header and add the attributes you want. Unfortunately, this:
+
+* doesn't work with attributes that must be present on a definition
+* doesn't allow changing the definition in other ways
+* requires your header to be included in any client code to take effect
+
+**Better solution:** Provide a "sidecar" file with the information you want to
+add, and have that automatically get picked up by the module-building logic in
+the compiler.
+
+That's API notes.
+
+API notes use a YAML-based file format. YAML is a format best explained by
+example, so here is a `small example`__ from the compiler test suite of API
+notes for a hypothetical "SomeKit" framework.
+
+__ test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.apinotes
+
+
+Usage
+=====
+
+API notes files are found relative to the module map that defines a module,
+under the name "SomeKit.apinotes" for a module named "SomeKit". Additionally, a
+file named "SomeKit_private.apinotes" will also be picked up to go with a
+private module map. For bare modules these two files will be in the same
+directory as the corresponding module map; for framework modules, they should
+be placed in the Headers and PrivateHeaders directories, respectively. The
+module map for a private top-level framework module should be placed in the
+PrivateHeaders directory as well, though it does not need an additional
+"_private" suffix on its name.
+
+Clang will search for API notes files next to module maps only when passed the
+``-fapi-notes-modules`` option.
+
+
+Limitations
+===========
+
+- Since they're identified by module name, API notes cannot be used to modify
+  arbitrary textual headers.
+
+
+"Versioned" API Notes
+=====================
+
+Many API notes affect how a C API is imported into Swift. In order to change
+that behavior while still remaining backwards-compatible, API notes can be
+selectively applied based on the Swift compatibility version provided to the
+compiler (e.g. ``-fapi-notes-swift-version=5``). The rule is that an
+explicitly-versioned API note applies to that version *and all earlier
+versions,* and any applicable explicitly-versioned API note takes precedence
+over an unversioned API note.
+
+
+Reference
+=========
+
+An API notes file contains a YAML dictionary with the following top-level
+entries:
+
+:Name:
+
+  The name of the module (the framework name, for frameworks). Note that this
+  is always the name of a top-level module, even within a private API notes
+  file.
+
+  ::
+
+    Name: MyFramework
+
+:Classes, Protocols, Tags, Typedefs, Globals, Enumerators, Functions:
+
+  Arrays of top-level declarations. Each entry in the array must have a
+  'Name' key with its Objective-C name. "Tags" refers to structs, enums, and
+  unions; "Enumerators" refers to enum cases.
+
+  ::
+
+    Classes:
+    - Name: MyController
+      …
+    - Name: MyView
+      …
+
+:SwiftVersions:
+
+  Contains explicit information for backwards compatibility. Each entry in
+  the array contains a 'Version' key, which should be set to '4' for
+  annotations that only apply to Swift 4 mode and earlier. The other entries
+  in this dictionary are the same declaration entries as at the top level:
+  Classes, Protocols, Tags, Typedefs, Globals, Enumerators, and Functions.
+
+  ::
+
+    SwiftVersions:
+    - Version: 4
+      Classes: …
+      Protocols: …
+
+Each entry under 'Classes' and 'Protocols' can contain "Methods" and
+"Properties" arrays, in addition to the attributes described below:
+
+:Methods:
+
+  Identified by 'Selector' and 'MethodKind'; the MethodKind is either
+  "Instance" or "Class".
+
+  ::
+
+    Classes:
+    - Name: UIViewController
+      Methods:
+      - Selector: "presentViewController:animated:"
+        MethodKind: Instance
+        …
+
+:Properties:
+
+  Identified by 'Name' and 'PropertyKind'; the PropertyKind is also either
+  "Instance" or "Class".
+
+  ::
+
+    Classes:
+    - Name: UIView
+      Properties:
+      - Name: subviews
+        PropertyKind: Instance
+        …
+
+Each declaration supports the following annotations (if relevant to that
+declaration kind), all of which are optional:
+
+:SwiftName:
+
+  Equivalent to ``NS_SWIFT_NAME``. For a method, must include the full Swift name
+  with all arguments. Use "_" to omit an argument label.
+
+  ::
+
+    - Selector: "presentViewController:animated:"
+      MethodKind: Instance
+      SwiftName: "present(_:animated:)"
+
+    - Class: NSBundle
+      SwiftName: Bundle
+
+:Availability, AvailabilityMsg:
+
+  A value of "nonswift" is equivalent to ``NS_SWIFT_UNAVAILABLE``. A value of
+  "available" can be used in the "SwiftVersions" section to undo the effect of
+  "nonswift".
+
+  ::
+
+    - Selector: "dealloc"
+      MethodKind: Instance
+      Availability: nonswift
+      AvailabilityMsg: "prefer 'deinit'"
+
+:SwiftPrivate:
+
+  Equivalent to NS_REFINED_FOR_SWIFT.
+
+  ::
+
+    - Name: CGColorEqualToColor
+      SwiftPrivate: true
+
+:Nullability:
+
+  Used for properties and globals. There are four options, identified by their
+  initials:
+
+  - ``Nonnull`` or ``N`` (corresponding to ``_Nonnull``)
+  - ``Optional`` or ``O`` (corresponding to ``_Nullable``)
+  - ``Unspecified`` or ``U`` (corresponding to ``_Null_unspecified``)
+  - ``Scalar`` or ``S`` (deprecated)
+
+  Note that 'Nullability' is overridden by 'Type', even in a "SwiftVersions"
+  section.
+
+  .. note::
+
+    'Nullability' can also be used to describe the argument types of methods
+    and functions, but this usage is deprecated in favor of 'Parameters' (see
+    below).
+
+  ::
+
+    - Name: dataSource
+      Nullability: O
+
+:NullabilityOfRet:
+
+  Used for methods and functions. Describes the nullability of the return type.
+
+  Note that 'NullabilityOfRet' is overridden by 'ResultType', even in a
+  "SwiftVersions" section.
+
+  .. warning::
+
+    Due to a compiler bug, 'NullabilityOfRet' may change nullability of the
+    parameters as well (rdar://30544062). Avoid using it and instead use
+    'ResultType' and specify the return type along with a nullability
+    annotation (see documentation for 'ResultType').
+
+  ::
+
+    - Selector: superclass
+      MethodKind: Class
+      NullabilityOfRet: O
+
+:Type:
+
+  Used for properties and globals. This completely overrides the type of the
+  declaration; it should ideally only be used for Swift backwards
+  compatibility, when existing type information has been made more precise in a
+  header. Prefer 'Nullability' and other annotations when possible.
+
+  We parse the specified type as if it appeared at the location of the
+  declaration whose type is being modified.  Macros are not available and
+  nullability must be applied explicitly (even in an ``NS_ASSUME_NONNULL_BEGIN``
+  section).
+
+  ::
+
+    - Name: delegate
+      PropertyKind: Instance
+      Type: "id"
+
+:ResultType:
+
+  Used for methods and functions. This completely overrides the return type; it
+  should ideally only be used for Swift backwards compatibility, when existing
+  type information has been made more precise in a header.
+
+  We parse the specified type as if it appeared at the location of the
+  declaration whose type is being modified.  Macros are not available and
+  nullability must be applied explicitly (even in an ``NS_ASSUME_NONNULL_BEGIN``
+  section).
+
+  ::
+
+    - Selector: "subviews"
+      MethodKind: Instance
+      ResultType: "NSArray * _Nonnull"
+
+:SwiftImportAsAccessors:
+
+  Used for properties. If true, the property will be exposed in Swift as its
+  accessor methods, rather than as a computed property using ``var``.
+
+  ::
+
+    - Name: currentContext
+      PropertyKind: Class
+      SwiftImportAsAccessors: true
+
+:NSErrorDomain:
+
+  Used for ``NSError`` code enums. The value is the name of the associated
+  domain ``NSString`` constant; an empty string (``""``) means the enum is a
+  normal enum rather than an error code.
+
+  ::
+
+    - Name: MKErrorCode
+      NSErrorDomain: MKErrorDomain
+
+:SwiftWrapper:
+
+  Controls ``NS_STRING_ENUM`` and ``NS_EXTENSIBLE_STRING_ENUM``. There are three
+  options:
+
+  - "struct" (extensible)
+  - "enum"
+  - "none"
+
+  Note that even an "enum" wrapper is still presented as a struct in Swift;
+  it's just a "more enum-like" struct.
+
+  ::
+
+    - Name: AVMediaType
+      SwiftWrapper: none
+
+:EnumKind:
+
+  Has the same effect as ``NS_ENUM`` and ``NS_OPTIONS``. There are four options:
+
+  - "NSEnum" / "CFEnum"
+  - "NSClosedEnum" / "CFClosedEnum"
+  - "NSOptions" / "CFOptions"
+  - "none"
+
+  ::
+
+    - Name: GKPhotoSize
+      EnumKind: none
+
+:Parameters:
+
+  Used for methods and functions. Parameters are identified by a 0-based
+  'Position' and support the 'Nullability', 'NoEscape', and 'Type' keys.
+
+  .. note::
+
+    Using 'Parameters' within a parameter entry to describe the parameters of a
+    block is not implemented. Use 'Type' on the entire parameter instead.
+
+  ::
+
+    - Selector: "isEqual:"
+      MethodKind: Instance
+      Parameters:
+      - Position: 0
+        Nullability: O
+
+:NoEscape:
+
+  Used only for block parameters. Equivalent to ``NS_NOESCAPE``.
+
+  ::
+
+    - Name: dispatch_sync
+      Parameters:
+      - Position: 0
+        NoEscape: true
+
+:SwiftBridge:
+
+  Used for Objective-C class types bridged to Swift value types. An empty
+  string ("") means a type is not bridged. Not supported outside of Apple
+  frameworks (the Swift side of it requires conforming to implementation-detail
+  protocols that are subject to change).
+
+  ::
+
+    - Name: NSIndexSet
+      SwiftBridge: IndexSet
+
+:DesignatedInit:
+
+  Used for init methods. Equivalent to ``NS_DESIGNATED_INITIALIZER``.
+
+  ::
+
+    - Selector: "initWithFrame:"
+      MethodKind: Instance
+      DesignatedInit: true
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to