C-family: Add attribute 'unavailable'.
authorIain Sandoe <iain@sandoe.co.uk>
Sun, 8 Nov 2020 09:04:07 +0000 (09:04 +0000)
committerIain Sandoe <iain@sandoe.co.uk>
Wed, 1 Sep 2021 14:09:38 +0000 (15:09 +0100)
commit8433baadec88e5f31fa141b6d78094e91256079d
treebbe8d1332389ecdee6c6849b903c0aa5d12c978d
parent21b4d0ef543d68187d258415b51d0d6676af89fd
C-family: Add attribute 'unavailable'.

If an interface is marked 'deprecated' then, presumably, at some point it
will be withdrawn and no longer available.  The 'unavailable' attribute
makes it possible to mark up interfaces to indicate this status.  It is used
quite extensively in some codebases where a single set of headers can be used
to permit code generation for multiple system versions.

From a configuration perspective, it also allows a compile test to determine
that an interface is missing - rather than requiring a link test.

The implementation follows the pattern of attribute deprecated, but produces
an error (where deprecation produces a warning).

This attribute has been implemented in clang for some years.

Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
gcc/c-family/ChangeLog:

* c-attribs.c (handle_unavailable_attribute): New.

gcc/c/ChangeLog:

* c-decl.c (enum deprecated_states): Add unavailable state.
(merge_decls): Copy unavailability.
(quals_from_declspecs): Handle unavailable case.
(start_decl): Amend the logic handling suppression of nested
deprecation states to include unavailability.
(smallest_type_quals_location): Amend comment.
(grokdeclarator): Handle the unavailable deprecation state.
(declspecs_add_type): Set TREE_UNAVAILABLE from the decl specs.
* c-tree.h (struct c_declspecs): Add unavailable_p.
* c-typeck.c (build_component_ref): Handle unavailability.
(build_external_ref): Likewise.

gcc/cp/ChangeLog:

* call.c (build_over_call): Handle unavailable state in addition to
deprecation.
* class.c (type_build_ctor_call): Likewise.
(type_build_dtor_call): Likewise.
* cp-tree.h: Rename cp_warn_deprecated_use to
cp_handle_deprecated_or_unavailable.
* decl.c (duplicate_decls): Merge unavailability.
(grokdeclarator): Handle unavailability in addition to deprecation.
(type_is_unavailable): New.
(grokparms): Handle unavailability in addition to deprecation.
* decl.h (enum deprecated_states): Add
UNAVAILABLE_DEPRECATED_SUPPRESS.
* decl2.c (cplus_decl_attributes): Propagate unavailability to
templates.
(cp_warn_deprecated_use): Rename to ...
(cp_handle_deprecated_or_unavailable): ... this and amend to handle
the unavailable case. It remains a warning in the case of deprecation
but becomes an error in the case of unavailability.
(cp_warn_deprecated_use_scopes): Handle unavailability.
(mark_used): Likewise.
* parser.c (cp_parser_template_name): Likewise.
(cp_parser_template_argument): Likewise.
(cp_parser_parameter_declaration_list): Likewise.
* typeck.c (build_class_member_access_expr): Likewise.
(finish_class_member_access_expr): Likewise.
* typeck2.c (build_functional_cast_1): Likewise.

gcc/ChangeLog:

* doc/extend.texi: Document unavailable attribute.
* print-tree.c (print_node): Handle unavailable attribute.
* tree-core.h (struct tree_base): Add a bit to carry unavailability.
* tree.c (error_unavailable_use): New.
* tree.h (TREE_UNAVAILABLE): New.
(error_unavailable_use): New.

gcc/objc/ChangeLog:

* objc-act.c (objc_add_property_declaration): Register unavailable
attribute.
(maybe_make_artificial_property_decl): Set available.
(objc_maybe_build_component_ref): Generalise to the method prototype
to count availability.
(objc_build_class_component_ref): Likewise.
(build_private_template): Likewise.
(objc_decl_method_attributes): Handle unavailable attribute.
(lookup_method_in_hash_lists): Amend comments.
(objc_finish_message_expr): Handle unavailability in addition to
deprecation.
(start_class): Likewise.
(finish_class): Likewise.
(lookup_protocol): Likewise.
(objc_declare_protocol): Likewise.
(start_protocol): Register unavailable attribute.
(really_start_method): Likewise.
(objc_gimplify_property_ref): Emit error on encountering an
unavailable entity (and a warning for a deprecated one).

gcc/testsuite/ChangeLog:

* g++.dg/ext/attr-unavailable-1.C: New test.
* g++.dg/ext/attr-unavailable-2.C: New test.
* g++.dg/ext/attr-unavailable-3.C: New test.
* g++.dg/ext/attr-unavailable-4.C: New test.
* g++.dg/ext/attr-unavailable-5.C: New test.
* g++.dg/ext/attr-unavailable-6.C: New test.
* g++.dg/ext/attr-unavailable-7.C: New test.
* g++.dg/ext/attr-unavailable-8.C: New test.
* g++.dg/ext/attr-unavailable-9.C: New test.
* gcc.dg/attr-unavailable-1.c: New test.
* gcc.dg/attr-unavailable-2.c: New test.
* gcc.dg/attr-unavailable-3.c: New test.
* gcc.dg/attr-unavailable-4.c: New test.
* gcc.dg/attr-unavailable-5.c: New test.
* gcc.dg/attr-unavailable-6.c: New test.
* obj-c++.dg/attributes/method-unavailable-1.mm: New test.
* obj-c++.dg/attributes/method-unavailable-2.mm: New test.
* obj-c++.dg/attributes/method-unavailable-3.mm: New test.
* obj-c++.dg/property/at-property-unavailable-1.mm: New test.
* obj-c++.dg/property/at-property-unavailable-2.mm: New test.
* obj-c++.dg/property/dotsyntax-unavailable-1.mm: New test.
* objc.dg/attributes/method-unavailable-1.m: New test.
* objc.dg/attributes/method-unavailable-2.m: New test.
* objc.dg/attributes/method-unavailable-3.m: New test.
* objc.dg/property/at-property-unavailable-1.m: New test.
* objc.dg/property/at-property-unavailable-2.m: New test.
* objc.dg/property/dotsyntax-unavailable-1.m: New test.
46 files changed:
gcc/c-family/c-attribs.c
gcc/c/c-decl.c
gcc/c/c-tree.h
gcc/c/c-typeck.c
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl.h
gcc/cp/decl2.c
gcc/cp/parser.c
gcc/cp/typeck.c
gcc/cp/typeck2.c
gcc/doc/extend.texi
gcc/objc/objc-act.c
gcc/print-tree.c
gcc/testsuite/g++.dg/ext/attr-unavailable-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/attr-unavailable-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/attr-unavailable-3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/attr-unavailable-4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/attr-unavailable-5.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/attr-unavailable-6.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/attr-unavailable-7.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/attr-unavailable-8.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/attr-unavailable-9.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/attr-unavailable-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/attr-unavailable-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/attr-unavailable-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/attr-unavailable-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/attr-unavailable-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/attr-unavailable-6.c [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/attributes/method-unavailable-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/attributes/method-unavailable-2.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/attributes/method-unavailable-3.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/property/at-property-unavailable-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/property/at-property-unavailable-2.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/property/dotsyntax-unavailable-1.mm [new file with mode: 0644]
gcc/testsuite/objc.dg/attributes/method-unavailable-1.m [new file with mode: 0644]
gcc/testsuite/objc.dg/attributes/method-unavailable-2.m [new file with mode: 0644]
gcc/testsuite/objc.dg/attributes/method-unavailable-3.m [new file with mode: 0644]
gcc/testsuite/objc.dg/property/at-property-unavailable-1.m [new file with mode: 0644]
gcc/testsuite/objc.dg/property/at-property-unavailable-2.m [new file with mode: 0644]
gcc/testsuite/objc.dg/property/dotsyntax-unavailable-1.m [new file with mode: 0644]
gcc/tree-core.h
gcc/tree.c
gcc/tree.h