[ CC'ing Sandra: since you were recently cleaning up the attributes docs (thanks), the doc/extend.texi bits in this patch might be of interest to you. ]
On Wed, May 06, 2015 at 08:44:10PM +0200, Marek Polacek wrote: > 2015-05-06 Marek Polacek <pola...@redhat.com> > > PR c/47043 > * c-common.c (handle_deprecated_attribute): Allow CONST_DECL. > > * c-parser.c (c_parser_enum_specifier): Parse and apply enumerator > attributes. > > * cp-tree.h (build_enumerator): Update declaration. > * decl.c (build_enumerator): Add attributes parameter. Call > cplus_decl_attributes. > * init.c (constant_value_1): Pass 0 to mark_used. > * parser.c (cp_parser_enumerator_definition): Parse attributes and > pass them down to build_enumerator. > * pt.c (tsubst_enum): Pass NULL_TREE to build_enumerator. > * semantics.c (finish_id_expression): Don't warn_deprecated_use here. > > * doc/extend.texi (Enumerator Attributes): New section. > Document syntax of enumerator attributes. > > * c-c++-common/attributes-enum-1.c: New test. > * c-c++-common/attributes-enum-2.c: New test. > * g++.dg/cpp0x/attributes-enum-1.C: New test. > > diff --git gcc/c-family/c-common.c gcc/c-family/c-common.c > index ada8e8a..36968e5 100644 > --- gcc/c-family/c-common.c > +++ gcc/c-family/c-common.c > @@ -8810,6 +8810,7 @@ handle_deprecated_attribute (tree *node, tree name, > || TREE_CODE (decl) == VAR_DECL > || TREE_CODE (decl) == FUNCTION_DECL > || TREE_CODE (decl) == FIELD_DECL > + || TREE_CODE (decl) == CONST_DECL > || objc_method_decl (TREE_CODE (decl))) > TREE_DEPRECATED (decl) = 1; > else > diff --git gcc/c/c-parser.c gcc/c/c-parser.c > index bf0e4c57..889e6d7 100644 > --- gcc/c/c-parser.c > +++ gcc/c/c-parser.c > @@ -2516,6 +2516,13 @@ c_parser_declspecs (c_parser *parser, struct > c_declspecs *specs, > enumerator: > enumeration-constant > enumeration-constant = constant-expression > + > + GNU Extensions: > + > + enumerator: > + enumeration-constant attributes[opt] > + enumeration-constant attributes[opt] = constant-expression > + > */ > > static struct c_typespec > @@ -2575,6 +2582,8 @@ c_parser_enum_specifier (c_parser *parser) > c_parser_set_source_position_from_token (token); > decl_loc = value_loc = token->location; > c_parser_consume_token (parser); > + /* Parse any specified attributes. */ > + tree enum_attrs = c_parser_attributes (parser); > if (c_parser_next_token_is (parser, CPP_EQ)) > { > c_parser_consume_token (parser); > @@ -2584,7 +2593,9 @@ c_parser_enum_specifier (c_parser *parser) > else > enum_value = NULL_TREE; > enum_decl = build_enumerator (decl_loc, value_loc, > - &the_enum, enum_id, enum_value); > + &the_enum, enum_id, enum_value); > + if (enum_attrs) > + decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0); > TREE_CHAIN (enum_decl) = values; > values = enum_decl; > seen_comma = false; > diff --git gcc/cp/cp-tree.h gcc/cp/cp-tree.h > index e0fbf5e..6b26cb1 100644 > --- gcc/cp/cp-tree.h > +++ gcc/cp/cp-tree.h > @@ -5400,7 +5400,7 @@ extern bool xref_basetypes (tree, > tree); > extern tree start_enum (tree, tree, tree, > bool, bool *); > extern void finish_enum_value_list (tree); > extern void finish_enum (tree); > -extern void build_enumerator (tree, tree, tree, location_t); > +extern void build_enumerator (tree, tree, tree, tree, > location_t); > extern tree lookup_enumerator (tree, tree); > extern bool start_preparsed_function (tree, tree, int); > extern bool start_function (cp_decl_specifier_seq *, > diff --git gcc/cp/decl.c gcc/cp/decl.c > index 261a12d..ebbd585 100644 > --- gcc/cp/decl.c > +++ gcc/cp/decl.c > @@ -13067,11 +13067,12 @@ finish_enum (tree enumtype) > > /* Build and install a CONST_DECL for an enumeration constant of the > enumeration type ENUMTYPE whose NAME and VALUE (if any) are provided. > - LOC is the location of NAME. > + Apply ATTRIBUTES if available. LOC is the location of NAME. > Assignment of sequential values by default is handled here. */ > > void > -build_enumerator (tree name, tree value, tree enumtype, location_t loc) > +build_enumerator (tree name, tree value, tree enumtype, tree attributes, > + location_t loc) > { > tree decl; > tree context; > @@ -13234,6 +13235,9 @@ incremented enumerator value is too large for > %<long%>"); > TREE_READONLY (decl) = 1; > DECL_INITIAL (decl) = value; > > + if (attributes) > + cplus_decl_attributes (&decl, attributes, 0); > + > if (context && context == current_class_type && !SCOPED_ENUM_P (enumtype)) > /* In something like `struct S { enum E { i = 7 }; };' we put `i' > on the TYPE_FIELDS list for `S'. (That's so that you can say > diff --git gcc/cp/init.c gcc/cp/init.c > index c41e30c..9298f2d 100644 > --- gcc/cp/init.c > +++ gcc/cp/init.c > @@ -2035,7 +2035,7 @@ constant_value_1 (tree decl, bool strict_p, bool > return_aggregate_cst_ok_p) > specialization, we must instantiate it here. The > initializer for the static data member is not processed > until needed; we need it now. */ > - mark_used (decl); > + mark_used (decl, 0); > mark_rvalue_use (decl); > init = DECL_INITIAL (decl); > if (init == error_mark_node) > diff --git gcc/cp/parser.c gcc/cp/parser.c > index 30a3fab..420759e 100644 > --- gcc/cp/parser.c > +++ gcc/cp/parser.c > @@ -16056,7 +16056,13 @@ cp_parser_enumerator_list (cp_parser* parser, tree > type) > enumerator = constant-expression > > enumerator: > - identifier */ > + identifier > + > + GNU Extensions: > + > + enumerator-definition: > + enumerator attributes [opt] > + enumerator attributes [opt] = constant-expression */ > > static void > cp_parser_enumerator_definition (cp_parser* parser, tree type) > @@ -16074,6 +16080,9 @@ cp_parser_enumerator_definition (cp_parser* parser, > tree type) > if (identifier == error_mark_node) > return; > > + /* Parse any specified attributes. */ > + tree attrs = cp_parser_attributes_opt (parser); > + > /* If the next token is an '=', then there is an explicit value. */ > if (cp_lexer_next_token_is (parser->lexer, CPP_EQ)) > { > @@ -16091,7 +16100,7 @@ cp_parser_enumerator_definition (cp_parser* parser, > tree type) > value = error_mark_node; > > /* Create the enumerator. */ > - build_enumerator (identifier, value, type, loc); > + build_enumerator (identifier, value, type, attrs, loc); > } > > /* Parse a namespace-name. > diff --git gcc/cp/pt.c gcc/cp/pt.c > index 8e0e789..c3a452d 100644 > --- gcc/cp/pt.c > +++ gcc/cp/pt.c > @@ -20686,8 +20686,8 @@ tsubst_enum (tree tag, tree newtag, tree args) > set_current_access_from_decl (decl); > > /* Actually build the enumerator itself. */ > - build_enumerator > - (DECL_NAME (decl), value, newtag, DECL_SOURCE_LOCATION (decl)); > + build_enumerator (DECL_NAME (decl), value, newtag, NULL_TREE, > + DECL_SOURCE_LOCATION (decl)); > } > > if (SCOPED_ENUM_P (newtag)) > diff --git gcc/cp/semantics.c gcc/cp/semantics.c > index 701a8eb..b46c6fc 100644 > --- gcc/cp/semantics.c > +++ gcc/cp/semantics.c > @@ -3651,11 +3651,6 @@ finish_id_expression (tree id_expression, > } > } > > - /* Handle references (c++/56130). */ > - tree t = REFERENCE_REF_P (decl) ? TREE_OPERAND (decl, 0) : decl; > - if (TREE_DEPRECATED (t)) > - warn_deprecated_use (t, NULL_TREE); > - > return decl; > } > > diff --git gcc/doc/extend.texi gcc/doc/extend.texi > index c290059..4337a32 100644 > --- gcc/doc/extend.texi > +++ gcc/doc/extend.texi > @@ -59,6 +59,7 @@ extensions, accepted by GCC in C90 mode and in C++. > * Variable Attributes:: Specifying attributes of variables. > * Type Attributes:: Specifying attributes of types. > * Label Attributes:: Specifying attributes on labels. > +* Enumerator Attributes:: Specifying attributes on enumerators. > * Attribute Syntax:: Formal syntax for attributes. > * Function Prototypes:: Prototype declarations and old-style definitions. > * C++ Comments:: C++ comments are recognized. > @@ -2175,6 +2176,7 @@ attribute syntax and placement. > GCC also supports attributes on > variable declarations (@pxref{Variable Attributes}), > labels (@pxref{Label Attributes}), > +enumerators (@pxref{Enumerator Attributes}), > and types (@pxref{Type Attributes}). > > There is some overlap between the purposes of attributes and pragmas > @@ -5041,8 +5043,9 @@ by an attribute specification inside double > parentheses. Some > attributes are currently defined generically for variables. > Other attributes are defined for variables on particular target > systems. Other attributes are available for functions > -(@pxref{Function Attributes}), labels (@pxref{Label Attributes}) and for > -types (@pxref{Type Attributes}). > +(@pxref{Function Attributes}), labels (@pxref{Label Attributes}), > +enumerators (@pxref{Enumerator Attributes}), and for types > +(@pxref{Type Attributes}). > Other front ends might define more attributes > (@pxref{C++ Extensions,,Extensions to the C++ Language}). > > @@ -5837,7 +5840,8 @@ attributes of types. Some type attributes apply only > to @code{struct} > and @code{union} types, while others can apply to any type defined > via a @code{typedef} declaration. Other attributes are defined for > functions (@pxref{Function Attributes}), labels (@pxref{Label > -Attributes}) and for variables (@pxref{Variable Attributes}). > +Attributes}), enumerators (@pxref{Enumerator Attributes}), and for > +variables (@pxref{Variable Attributes}). > > The @code{__attribute__} keyword is followed by an attribute specification > inside double parentheses. > @@ -6300,7 +6304,8 @@ compilers to match the native Microsoft compiler. > GCC allows attributes to be set on C labels. @xref{Attribute Syntax}, for > details of the exact syntax for using attributes. Other attributes are > available for functions (@pxref{Function Attributes}), variables > -(@pxref{Variable Attributes}) and for types (@pxref{Type Attributes}). > +(@pxref{Variable Attributes}), enumerators (@xref{Enumerator Attributes}), > +and for types (@pxref{Type Attributes}). > > This example uses the @code{cold} label attribute to indicate the > @code{ErrorHandling} branch is unlikely to be taken and that the > @@ -6346,6 +6351,45 @@ with computed goto or @code{asm goto}. > > @end table > > +@node Enumerator Attributes > +@section Enumerator Attributes > +@cindex Enumerator Attributes > + > +GCC allows attributes to be set on enumerators. @xref{Attribute Syntax}, for > +details of the exact syntax for using attributes. Other attributes are > +available for functions (@pxref{Function Attributes}), variables > +(@pxref{Variable Attributes}), labels (@xref{Label Attributes}), > +and for types (@pxref{Type Attributes}). > + > +This example uses the @code{deprecated} enumerator attribute to indicate the > +@code{oldval} enumerator is deprecated: > + > +@smallexample > +enum E @{ > + oldval __attribute__((deprecated)), > + newval > +@}; > + > +int > +fn (void) > +@{ > + return oldval; > +@} > +@end smallexample > + > +@table @code > +@item deprecated > +@cindex @code{deprecated} enumerator attribute > +The @code{deprecated} attribute results in a warning if the enumerator > +is used anywhere in the source file. This is useful when identifying > +enumerators that are expected to be removed in a future version of a > +program. The warning also includes the location of the declaration > +of the deprecated enumerator, to enable users to easily find further > +information about why the enumerator is deprecated, or what they should > +do instead. Note that the warnings only occurs for uses. > + > +@end table > + > @node Attribute Syntax > @section Attribute Syntax > @cindex attribute syntax > @@ -6371,6 +6415,8 @@ for details of the semantics of attributes applying to > structure, union > and enumerated types. > @xref{Label Attributes}, for details of the semantics of attributes > applying to labels. > +@xref{Enumerator Attributes}, for details of the semantics of attributes > +applying to enumerators. > > An @dfn{attribute specifier} is of the form > @code{__attribute__ ((@var{attribute-list}))}. An @dfn{attribute list} > @@ -6428,6 +6474,14 @@ ambiguous, as it is permissible for a declaration, > which could begin > with an attribute list, to be labelled in C++. Declarations cannot be > labelled in C90 or C99, so the ambiguity does not arise there. > > +@subsubheading Enumerator Attributes > + > +In GNU C, an attribute specifier list may appear as part of an enumerator. > +The attribute goes after the enumeration constant, before @code{=}, if > +present. The optional attribute in the enumerator appertains to the > +enumeration constant. It is not possible to place the attribute after > +the constant expression, if present. > + > @subsubheading Type Attributes > > An attribute specifier list may appear as part of a @code{struct}, > diff --git gcc/testsuite/c-c++-common/attributes-enum-1.c > gcc/testsuite/c-c++-common/attributes-enum-1.c > index e69de29..cb5af5b 100644 > --- gcc/testsuite/c-c++-common/attributes-enum-1.c > +++ gcc/testsuite/c-c++-common/attributes-enum-1.c > @@ -0,0 +1,22 @@ > +/* Test enumerators with attributes. */ > +/* PR c/47043 */ > +/* { dg-do compile } */ > + > +enum E { > + A __attribute__((deprecated)), > + B __attribute__((deprecated ("foo"))), > + C __attribute__((deprecated)) = 10, > + D __attribute__((deprecated ("foo"))) = 15, > + E > +}; > + > +int > +f (int i) > +{ > + i += A; /* { dg-warning ".A. is deprecated" } */ > + i += B; /* { dg-warning ".B. is deprecated" } */ > + i += C; /* { dg-warning ".C. is deprecated" } */ > + i += D; /* { dg-warning ".D. is deprecated" } */ > + i += E; > + return i; > +} > diff --git gcc/testsuite/c-c++-common/attributes-enum-2.c > gcc/testsuite/c-c++-common/attributes-enum-2.c > index e69de29..df5bc9c 100644 > --- gcc/testsuite/c-c++-common/attributes-enum-2.c > +++ gcc/testsuite/c-c++-common/attributes-enum-2.c > @@ -0,0 +1,14 @@ > +/* Test enumerators with attributes. Test invalid uses. */ > +/* PR c/47043 */ > +/* { dg-do compile } */ > + > +enum E { > + A __attribute__((foo)), /* { dg-warning "ignored" } */ > + B __attribute__((cold)), /* { dg-warning "ignored" } */ > + C __attribute__((const)), /* { dg-warning "ignored" } */ > + D __attribute__((unused)), /* { dg-warning "ignored" } */ > + E __attribute__((flatten)), /* { dg-warning "ignored" } */ > + F __attribute__((tm)), /* { dg-warning "ignored" } */ > + G __attribute__((common)), /* { dg-warning "ignored" } */ > + H __attribute__((volatile)), /* { dg-warning "ignored" } */ > +}; > diff --git gcc/testsuite/g++.dg/cpp0x/attributes-enum-1.C > gcc/testsuite/g++.dg/cpp0x/attributes-enum-1.C > index e69de29..4146116 100644 > --- gcc/testsuite/g++.dg/cpp0x/attributes-enum-1.C > +++ gcc/testsuite/g++.dg/cpp0x/attributes-enum-1.C > @@ -0,0 +1,20 @@ > +// PR c/47046 > +// { dg-do compile { target c++11 } } > + > +enum E { > + A [[gnu::deprecated]] > +}; > + > +enum class F { > + B [[gnu::deprecated]], > + C __attribute__ ((deprecated)) > +}; > + > +int > +f (int i) > +{ > + F f1 = F::B; // { dg-warning ".B. is deprecated" } > + F f2 = F::C; // { dg-warning ".C. is deprecated" } > + i += A; // { dg-warning ".A. is deprecated" } > + return i; > +} > > Marek Marek