[PATCH] D69991: Implement __attribute__((objc_direct)), __attribute__((objc_direct_members))

John McCall via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 13 18:22:14 PST 2019


rjmccall added a comment.

Could you add tests for the following cases:

1. A direct property that names a getter that is non-direct and explicitly declared in the current interface.
2. #1, but explicitly declared elsewhere, maybe in a super class or in the primary interface.
3. #1 and #2, but where the property is only direct because of objc_direct_members.
4. A direct property that is making a previously-`readonly` direct property `readwrite`.
5. #4, but the previous property was not direct (only the setter should be direct).
6. #4 and #5, but with objc_direct_members.
7. A synthesized getter or setter in an objc_direct_members implementation (should follow the interface).
8. #7 but with auto-synthesis
9. The implicit `.cxx_destruct` and `.cxx_construct` methods in an objc_direct_members shouldn't get treated as direct.  This should not be remotely possible in the current implementation, but it's worth adding a test to verify that it doesn't start to happen.



================
Comment at: clang/include/clang/Basic/AttrDocs.td:3942
+and ``@interface`` blocks defining Categories or Extensions to mark methods
+as being direct calls in bulk.
+  }];
----------------
Okay, how's this as a tweak to the whole documentation:

The ``objc_direct`` attribute can be used to mark an Objective-C method as
being *direct*.  A direct method is treated statically like an ordinary method,
but dynamically it behaves more like a C function.  This lowers some of the costs
associated with the method but also sacrifices some of the ordinary capabilities
of Objective-C methods.

A message send of a direct method calls the implementation directly, as if it
were a C function, rather than using ordinary Objective-C method dispatch. This
is substantially faster and potentially allows the implementation to be inlined,
but it also means the method cannot be overridden in subclasses or replaced
dynamically, as ordinary Objective-C methods can.

Furthermore, a direct method is not listed in the class's method lists. This
substantially reduces the code-size overhead of the method but also means it
cannot be called dynamically using ordinary Objective-C method dispatch at all;
in particular, this means that it cannot override a superclass method or satisfy
a protocol requirement.

Although a message send of a direct method causes the method to be called
directly as if it were a C function, it still obeys Objective-C semantics in other
ways:

- If the receiver is ``nil``, the message send does nothing and returns the zero value
  for the return type.

- A message send of a direct class method will cause the class to be initialized,
  including calling the ``+initialize`` method if present.

- The implicit ``_cmd`` parameter containing the method's selector is still defined.
  In order to minimize code-size costs, the implementation will not emit a reference
  to the selector if the parameter is unused within the method.

Symbols for direct method implementations are implicitly given hidden
visibility, meaning that they can only be called within the same linkage unit.

It is an error to do any of the following:

- declare a direct method in a protocol,
- declare an override of a direct method with a method in a subclass,
- declare an override of a non-direct method with a direct method in a subclass,
- declare a method with different directness in different class interfaces, or
- implement a non-direct method (as declared in any class interface) with a direct method.

If any of these rules would be violated if every method defined in an
``@implementation`` within a single linkage unit were declared in an
appropriate class interface, the program is ill-formed with no diagnostic
required.  If a violation of this rule is not diagnosed, behavior remains
well-defined; this paragraph is simply reserving the right to diagnose such
conflicts in the future, not to treat them as undefined behavior.

Additionally, Clang will warn about any ``@selector`` expression that
names a selector that is only known to be used for direct methods.

For the purpose of these rules, a "class interface" includes a class's primary
``@interface`` block, its class extensions, its categories, its declared protocols,
and all the class interfaces of its superclasses.

An Objective-C property can be declared with the ``direct`` property
attribute.  If a direct property declaration causes an implicit declaration of
a getter or setter method (that is, if the given method is not explicitly
declared elsewhere), the method is declared to be direct.

Some programmers may wish to make many methods direct at once.  In order
to simplify this, the ``objc_direct_members`` attribute is provided; see its
documentation for more information.


================
Comment at: clang/include/clang/Basic/AttrDocs.td:3959
+or any of its superclass, as well as methods implementing an ``@protocol``
+conformance, are implicitly marked with the ``objc_direct`` attribute.
+  }];
----------------
The ``objc_direct_members`` attribute can be placed on an  Objective-C
``@interface`` or ``@implementation`` to mark that methods declared
therein should be considered direct by default.  See the documentation
for ``objc_direct`` for more information about direct methods.

When ``objc_direct_members`` is placed on an ``@interface`` block, every
method in the block is considered to be declared as direct.  This includes any
implicit method declarations introduced by property declarations.  If the method
redeclares a non-direct method, the declaration is ill-formed, exactly as if the
method was annotated with the ``objc_direct`` attribute.  ``objc_direct_members``
cannot be placed on the primary interface of a class, only on category or class
extension interfaces.

When ``objc_direct_members`` is placed on an ``@implementation`` block,
methods defined in the block are considered to be declared as direct unless
they have been previously declared as non-direct in any interface of the class.
This includes the implicit method definitions introduced by synthesized
properties, including auto-synthesized properties.


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

https://reviews.llvm.org/D69991





More information about the cfe-commits mailing list