G++ should support the generalized attributes feature presented in the N2761 paper at http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2761.pdf.
Note that the syntactic binding of C++11 attributes is different from that of GNU attributes in various cases, so the front end will need to track separately what attributes of each syntax have been used in various places.
If this feature is going to be used also for extended GNU attributes, it can be done via a special extension: [[gnu init_priority(200)]] [[gnu format(printf, 2, 3)]] would be same as: __attribute__ ((init_priority (200))) __attribute__ ((format(printf, 2, 3))) Some standard attributes can be also implemented as alias to existing gnu attributes, for example [[gnu noreturn]] would be the same as [[noreturn]]. Currently the only standard attributes are "noreturn" and "carries_dependency". They don't get any arguments, so I don't think the difference to current attribute syntax matters.
There's no need for an extension, the grammar allows [[gnu::init_priority(200)]]
A candidate implementation patch for this has been posted to http://gcc.gnu.org/ml/gcc-patches/2012-07/msg01348.html @Joseph: Thank you for the note. I believe the patch handles this, unless I have forgotten things. @Michal Malecki / Jonathan Wakely The scoped attributes syntax [[gnu::priority(200)]] is now supported. The patch has put all the GNU attributes in the "gnu" namespace by default. So now whenever one writes __attribute__((priority(200))), the priority attribute is looked up from or put into the "gnu" namespace. We'll see what comes out of the discussion that arises from the patch submission.
Looks nice. Is that a big deal if you also make a standard [[noreturn]] attribute simply an alias to [[gnu::noreturn]]? As far as I know the standard, they should behave exactly the same way. Another thing is that I think this should work, according to the standard: void quit [[gnu::noreturn]] () { throw 0; } And it doesn't with this patch. Of course, [[gnu::noreturn]] void quit()... works and is more intuitive, but both are required by the standard. I guess the difference is when you'd do this: int quit [[noreturn]](), pass(); // pass does return! while here both are noreturn: [[noreturn]] int quit(), pass();
Author: dodji Date: Mon Oct 8 09:29:05 2012 New Revision: 192199 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=192199 Log: PR c++/53528 C++11 attribute support This patch implements the c++-11 generalized attributes, described in the N2761 paper[1]. The idea is to modify the front-end to accept the new attribute syntax (including alignas expressions) and to build an internal representation similar to the one we already have for GNU attributes. This lets us re-use our existing GNU attribute mechanisms to support the generalized c++11 attributes. The patch does change the existing internal representation to support scoped attribute (aka attributes with namespaces), which is a concept that doesn't exist in GNU attributes. I have thus put all existing GNU extension attributes into the "gnu" namespace. For instance, in C++-11, the "unused" attribute would be represented as "[[gnu::unused]]". Because there is no syntax for scoped attributes in C, writting "__attribute__((unused))" unconditionnally refers to the "unused" attribute in the "gnu" namespace. Note that this patch follows a conservative understanding of the specification by disallowing attributes appertaining to types, unless they apply to a type definition. Tested on x86_64-unknown-linux-gnu and powerpc64-unknown-linux-gnu. [1]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2761.pdf gcc/ * plugin.h (register_scoped_attributes): Declare new function. * tree.h (enu attribute_flags::ATTR_FLAG_CXX_11): New flag. (lookup_scoped_attribute_spec, cxx_11_attribute_p) (get_attribute_name, get_attribute_namespace): Declare new functions. (struct attribute_spec): Remove const qualifier from the members. * tree.c (comp_type_attributes, private_lookup_attribute) (lookup_ident_attribute, remove_attribute, merge_attribute) (attribute_hash_list, attribute_list_contained): Use get_attribute_name. * attribs.c (decl_attributes): Don't crash on error_mark_node. Forbid c++11 attributes appertaining to type-specifiers. (attribute_hash): Remove global variable. (attributes_table): New global variable. (find_attribute_namespace, register_scoped_attribute): New static functions. (register_scoped_attributes, lookup_scoped_attribute_spec) (cxx11_attribute_p, get_attribute_name, get_attribute_namespace): New public functions. (init_attributes): Register all the GNU attributes into the "gnu" namespace. (register_attribute): Use register_scoped_attribute to register the attribute into the "gnu" namespace. (lookup_attribute_spec): Use lookup_scoped_attribute_spec to lookup the attribute in the "gnu" namespace. (decl_attributes): Use new get_attribute_namespace and lookup_scoped_attribute_spec to consider attribute namespaces when looking up attributes. When operating in c++-11 mode, pass flag ATTR_FLAG_CXX11 to the spec handler. gcc/c-family/ * c-common.h (bitfield_p, cxx_fundamental_alignment_p): Declare new functions. * c-common.c (check_cxx_fundamental_alignment_constraints): New static function. (handle_aligned_attribute): In choose strictest alignment among many. Use new check_cxx_fundamental_alignment_constraints. (handle_transparent_union_attribute): In c++11 attribute syntax, don't look through typedefs. gcc/cp/ * cp-tree.h (enum cpp0x_warn_str::CPP0X_ATTRIBUTES): New member. (enum cp_decl_spec::ds_std_attribute): New enumerator. (struct cp_decl_specifier_seq::std_attributes): New field. (cxx_alignas_expr, warn_misplaced_attr_for_class_type): Declare new functions. (check_tag_decl): Take an extra parameter for explicit instantiations. * decl.c (warn_misplaced_attr_for_class_type): Extract from ... (check_tag_decl): ... here. Add check for c++11 attributes being applied to an explicit instantiation. Take an extra parameter for explicit instantiations. (grokdeclarator): Make sure a c++11 attribute after an array declarator appertains to the array, an attribute after a function declarator appertains to the function type, an attribute after a declarator-id appertains to the entity being declared, and an attribute after a pointer declarator appertains to the pointer. * decl2.c (is_late_template_attribute): Use get_attribute_name. * error.c (maybe_warn_cpp0x): Support CPP0X_GENERALIZED_ATTRIBUTES. * parser.c (cp_next_tokens_can_be_attribute_p) (cp_next_tokens_can_be_gnu_attribute_p) (cp_next_tokens_can_be_std_attribute_p) (cp_nth_tokens_can_be_attribute_p) (cp_nth_tokens_can_be_gnu_attribute_p) (cp_nth_tokens_can_be_std_attribute_p) (cp_parser_gnu_attribute_list, cp_parser_std_attribute) (cp_parser_std_attribute_spec, cp_parser_std_attribute_spec_seq) (cp_parser_attributes_opt, cp_parser_std_attribute_list): New static functions. (cp_parser_gnu_attributes_opt): Replace cp_parser_attributes_opt. (cp_parser_gnu_attribute_list): Replace cp_parser_attribute_list. (cp_parser_postfix_expression): Disallow "[[" tokens here. (cp_parser_label_for_labeled_statement): Use take an extra parameter for attributes. (cp_parser_block_declaration): Use cp_nth_tokens_can_be_std_attribute_p here. (cp_parser_decl_specifier_seq): Likewise. Store C++11 attributes that appears in in decl specifiers in cp_decl_specifier_seq::std_attributes. declaration. Emit proper warning about misplaced c++11 attributes for class type. (cp_parser_explicit_instantiation): Adjust call to check_tag_decl. (cp_parser_init_declarator): Parsing attributes here is no more a GNU extension in c++-11. (cp_parser_type_specifier_seq): Use cp_next_tokens_can_be_attribute_p. (cp_parser_direct_declarator): Likewise. Hang c++11 attributes following the declarator to its syntactic construct. It'll later be applied to the proper appertaining entity by grokdeclarator. (cp_parser_ptr_operator): Likewise. (make_declarator): Initialize cp_declarator::std_attribute. (make_pointer_declarator, make_reference_declarator) (make_ptrmem_declarator, cp_parser_make_indirect_declarator): Take attributes that appertain to the pointer/reference in argument. (cp_parser_ptr_operator): Take an out parameter for c++11 attributes. Update comments. (cp_parser_new_declarator_opt) (cp_parser_conversion_declarator_opt): Adjust. (cp_parser_declarator): Likewise. Handle C++11 attributes. Rename attributes to gnu_attribute for better legibility. (cp_parser_simple_declaration): Update comment. (cp_parser_class_specifier_1): Parse GNU attributes specifically (cp_parser_enum_specifier): Accept only gnu attributes after the specifier. (cp_parser_member_declaration): Don't clear attributes -- intended for the entity being declared -- too early because check_tag_decl needs them. (cp_parser_statement): Update comment. Parse optional c++11 attributes at the beginning of the relevant kind of statements and ignore them, for now, unless when calling cp_parser_label_for_labeled_statement. (cp_parser_label_for_labeled_statement): Take c++11 attributes in parameter. * semantics.c (potential_constant_expression_1): Likewise. * typeck.c (fundamental_alignment_p, cxx_alignas_expr): New public functions. gcc/testsuite/ * g++.dg/cpp0x/gen-attrs-1.C: New test. * g++.dg/cpp0x/gen-attrs-2.C: Likewise. * g++.dg/cpp0x/gen-attrs-2-1.C: Likewise. * g++.dg/cpp0x/gen-attrs-3.C: Likewise. * g++.dg/cpp0x/gen-attrs-4.C: Likewise. * g++.dg/cpp0x/gen-attrs-5.C: Likewise. * g++.dg/cpp0x/gen-attrs-6.C: Likewise. * g++.dg/cpp0x/gen-attrs-7.C: Likewise. * g++.dg/cpp0x/gen-attrs-8.C: Likewise. * g++.dg/cpp0x/gen-attrs-9.C: Likewise. * g++.dg/cpp0x/gen-attrs-10.C: Likewise. * g++.dg/cpp0x/gen-attrs-11.C: Likewise. * g++.dg/cpp0x/gen-attrs-12.C: Likewise. * g++.dg/cpp0x/gen-attrs-13.C: Likewise. * g++.dg/cpp0x/gen-attrs-14.C: Likewise. * g++.dg/cpp0x/gen-attrs-15.C: Likewise. * g++.dg/cpp0x/gen-attrs-16.C: Likewise. * g++.dg/cpp0x/gen-attrs-17.C: Likewise. * g++.dg/cpp0x/gen-attrs-18.C: Likewise. * g++.dg/cpp0x/gen-attrs-19.C: Likewise. * g++.dg/cpp0x/gen-attrs-20.C: Likewise. * g++.dg/cpp0x/gen-attrs-21.C: Likewise. * g++.dg/cpp0x/gen-attrs-22.C: Likewise. * g++.dg/cpp0x/gen-attrs-23.C: Likewise. * g++.dg/cpp0x/gen-attrs-24.C: Likewise. * g++.dg/cpp0x/gen-attrs-25.C: Likewise. * g++.dg/cpp0x/gen-attrs-26.C: Likewise. * g++.dg/cpp0x/gen-attrs-27.C: Likewise. * g++.dg/cpp0x/gen-attrs-28.C: Likewise. * g++.dg/cpp0x/gen-attrs-29.C: Likewise. * g++.dg/cpp0x/gen-attrs-30.C: Likewise. * g++.dg/cpp0x/gen-attrs-31.C: Likewise. * g++.dg/cpp0x/gen-attrs-32.C: Likewise. * g++.dg/cpp0x/gen-attrs-33.C: Likewise. * g++.dg/cpp0x/gen-attrs-34.C: Likewise. * g++.dg/cpp0x/gen-attrs-35.C: Likewise. * g++.dg/cpp0x/gen-attrs-36.C: Likewise. * g++.dg/cpp0x/gen-attrs-36-1.C: Likewise. * g++.dg/cpp0x/gen-attrs-37.C: Likewise. * g++.dg/cpp0x/gen-attrs-38.C: Likewise. * g++.dg/cpp0x/gen-attrs-39.C: Likewise. * g++.dg/cpp0x/gen-attrs-39-1.C: Likewise. * g++.dg/cpp0x/gen-attrs-40.C: Likewise. * g++.dg/cpp0x/gen-attrs-41.C: Likewise. * g++.dg/cpp0x/gen-attrs-42.C: Likewise. * g++.dg/cpp0x/gen-attrs-43.C: Likewise. * g++.dg/cpp0x/gen-attrs-44.C: Likewise. * g++.dg/cpp0x/gen-attrs-45.C: Likewise. * g++.dg/cpp0x/gen-attrs-46.C: Likewise. * g++.dg/cpp0x/gen-attrs-47.C: Likewise. * g++.dg/cpp0x/gen-attrs-47-1.C: Likewise. * g++.dg/cpp0x/gen-attrs-48.C: Likewise. * g++.dg/cpp0x/gen-attrs-49.C: Likewise. * g++.dg/cpp0x/gen-attrs-50.C: Likewise. * g++.dg/cpp0x/gen-attrs-51.C: Likewise. * g++.dg/cpp0x/gen-attrs-52.C: Likewise. * g++.dg/cpp0x/gen-attrs-53.C: Likewise. Added: trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-1.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-10.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-11.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-12.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-13.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-14.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-15.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-16.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-17.2.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-17.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-18.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-19.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-2-1.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-2.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-20.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-21.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-22.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-23.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-24.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-25.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-26.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-27.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-28.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-29.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-3.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-30.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-31.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-32.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-33.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-34.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-35.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-36-1.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-36.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-37.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-38.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-39-1.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-39.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-4.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-40.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-41.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-42.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-43.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-44.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-45.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-46.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-47-1.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-47.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-48.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-49.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-5.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-50.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-51.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-52.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-53.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-6.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-7.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-8.C trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-9.C Modified: trunk/gcc/ChangeLog trunk/gcc/attribs.c trunk/gcc/c-family/ChangeLog trunk/gcc/c-family/c-common.c trunk/gcc/c-family/c-common.h trunk/gcc/cp/ChangeLog trunk/gcc/cp/cp-tree.h trunk/gcc/cp/decl.c trunk/gcc/cp/decl2.c trunk/gcc/cp/error.c trunk/gcc/cp/parser.c trunk/gcc/cp/typeck.c trunk/gcc/plugin.h trunk/gcc/testsuite/ChangeLog trunk/gcc/tree.c trunk/gcc/tree.h
Sorry Michal for getting to your comment this late. "ethouris at gmail dot com" <gcc-bugzilla@gcc.gnu.org> a écrit: > Looks nice. Is that a big deal if you also make a standard [[noreturn]] > attribute simply an alias to [[gnu::noreturn]]? The patch as it is focused on bringing in the core support for c++11 attributes. Supporting some attributes in particular is left as a follow-up to come up later. An exception to this is that the patch also supports alignas expressions, but that is just because it was needed to complete the support of the attributes syntax. > As far as I know the standard, they should behave exactly the same > way. I haven't looked at the details yet, but I think you are correct. > > Another thing is that I think this should work, according to the standard: > > void quit [[gnu::noreturn]] () { throw 0; } > > And it doesn't with this patch. I think it works with the version of the patch that I just committed. Or maybe I don't understand what you mean by "doesn't work". Thanks for caring.
Applied to trunk (4.8).