@@ -52,7 +52,6 @@ static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
5252static tree handle_transaction_pure_attribute (tree * , tree , tree , int , bool * );
5353static tree handle_returns_twice_attribute (tree * , tree , tree , int , bool * );
5454static tree handle_fnspec_attribute (tree * , tree , tree , int , bool * );
55- static tree handle_weakref_attribute (tree * , tree , tree , int , bool * );
5655
5756/* D attribute handlers for user defined attributes. */
5857static tree d_handle_noinline_attribute (tree * , tree , tree , int , bool * );
@@ -64,66 +63,104 @@ static tree d_handle_section_attribute (tree *, tree, tree, int, bool *);
6463static tree d_handle_alias_attribute (tree * , tree , tree , int , bool * );
6564static tree d_handle_weak_attribute (tree * , tree , tree , int , bool * ) ;
6665
66+ /* Helper to define attribute exclusions. */
67+ #define ATTR_EXCL (name , function , type , variable ) \
68+ { name, function, type, variable }
69+
70+ /* Define attributes that are mutually exclusive with one another. */
71+ static const struct attribute_spec ::exclusions attr_noreturn_exclusions [] =
72+ {
73+ ATTR_EXCL ("noreturn" , true, true, true),
74+ ATTR_EXCL ("const" , true, true, true),
75+ ATTR_EXCL ("malloc" , true, true, true),
76+ ATTR_EXCL ("pure" , true, true, true),
77+ ATTR_EXCL ("returns_twice" , true, true, true),
78+ ATTR_EXCL (NULL , false, false, false),
79+ };
80+
81+ static const struct attribute_spec ::exclusions attr_returns_twice_exclusions [] =
82+ {
83+ ATTR_EXCL ("noreturn" , true, true, true),
84+ ATTR_EXCL (NULL , false, false, false),
85+ };
86+
87+ static const struct attribute_spec ::exclusions attr_const_pure_exclusions [] =
88+ {
89+ ATTR_EXCL ("const" , true, true, true),
90+ ATTR_EXCL ("noreturn" , true, true, true),
91+ ATTR_EXCL ("pure" , true, true, true),
92+ ATTR_EXCL (NULL , false, false, false)
93+ };
94+
95+ static const struct attribute_spec ::exclusions attr_inline_exclusions [] =
96+ {
97+ ATTR_EXCL ("noinline" , true, true, true),
98+ ATTR_EXCL (NULL , false, false, false),
99+ };
100+
101+ static const struct attribute_spec ::exclusions attr_noinline_exclusions [] =
102+ {
103+ ATTR_EXCL ("forceinline" , true, true, true),
104+ ATTR_EXCL (NULL , false, false, false),
105+ };
106+
107+ /* Helper to define an attribute. */
108+ #define ATTR_SPEC (name , min_len , max_len , decl_req , type_req , fn_type_req , \
109+ affects_type_identity , handler , exclude ) \
110+ { name, min_len, max_len, decl_req, type_req, fn_type_req, \
111+ affects_type_identity, handler, exclude }
67112
68113/* Table of machine-independent attributes.
69114 For internal use (marking of builtins) only. */
70-
71115const attribute_spec d_langhook_common_attribute_table [] =
72116{
73- /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
74- affects_type_identity } */
75- { "noreturn" , 0 , 0 , true, false, false,
76- handle_noreturn_attribute , false },
77- { "leaf" , 0 , 0 , true, false, false,
78- handle_leaf_attribute , false },
79- { "const" , 0 , 0 , true, false, false,
80- handle_const_attribute , false },
81- { "malloc" , 0 , 0 , true, false, false,
82- handle_malloc_attribute , false },
83- { "returns_twice" , 0 , 0 , true, false, false,
84- handle_returns_twice_attribute , false },
85- { "pure" , 0 , 0 , true, false, false,
86- handle_pure_attribute , false },
87- { "nonnull" , 0 , -1 , false, true, true,
88- handle_nonnull_attribute , false },
89- { "nothrow" , 0 , 0 , true, false, false,
90- handle_nothrow_attribute , false },
91- { "transaction_pure" , 0 , 0 , false, true, true,
92- handle_transaction_pure_attribute , false },
93- { "no vops" , 0 , 0 , true, false, false,
94- handle_novops_attribute , false },
95- { "type generic" , 0 , 0 , false, true, true,
96- handle_type_generic_attribute , false },
97- { "fn spec" , 1 , 1 , false, true, true,
98- handle_fnspec_attribute , false },
99- { "weakref" , 0 , 1 , true, false, false,
100- handle_weakref_attribute , false },
101- { NULL , 0 , 0 , false, false, false, NULL , false }
117+ ATTR_SPEC ("noreturn" , 0 , 0 , true, false, false, false,
118+ handle_noreturn_attribute , attr_noreturn_exclusions ),
119+ ATTR_SPEC ("leaf" , 0 , 0 , true, false, false, false,
120+ handle_leaf_attribute , NULL ),
121+ ATTR_SPEC ("const" , 0 , 0 , true, false, false, false,
122+ handle_const_attribute , attr_const_pure_exclusions ),
123+ ATTR_SPEC ("malloc" , 0 , 0 , true, false, false, false,
124+ handle_malloc_attribute , NULL ),
125+ ATTR_SPEC ("returns_twice" , 0 , 0 , true, false, false, false,
126+ handle_returns_twice_attribute , attr_returns_twice_exclusions ),
127+ ATTR_SPEC ("pure" , 0 , 0 , true, false, false, false,
128+ handle_pure_attribute , attr_const_pure_exclusions ),
129+ ATTR_SPEC ("nonnull" , 0 , -1 , false, true, true, false,
130+ handle_nonnull_attribute , NULL ),
131+ ATTR_SPEC ("nothrow" , 0 , 0 , true, false, false, false,
132+ handle_nothrow_attribute , NULL ),
133+ ATTR_SPEC ("transaction_pure" , 0 , 0 , false, true, true, false,
134+ handle_transaction_pure_attribute , NULL ),
135+ ATTR_SPEC ("no vops" , 0 , 0 , true, false, false, false,
136+ handle_novops_attribute , NULL ),
137+ ATTR_SPEC ("type generic" , 0 , 0 , false, true, true, false,
138+ handle_type_generic_attribute , NULL ),
139+ ATTR_SPEC ("fn spec" , 1 , 1 , false, true, true, false,
140+ handle_fnspec_attribute , NULL ),
141+ ATTR_SPEC (NULL , 0 , 0 , false, false, false, false, NULL , NULL ),
102142};
103143
104144/* Table of D language attributes exposed by `gcc.attribute' UDAs. */
105-
106145const attribute_spec d_langhook_attribute_table [] =
107146{
108- /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
109- affects_type_identity } */
110- { "noinline" , 0 , 0 , true, false, false,
111- d_handle_noinline_attribute , false },
112- { "forceinline" , 0 , 0 , true, false, false,
113- d_handle_forceinline_attribute , false },
114- { "flatten" , 0 , 0 , true, false, false,
115- d_handle_flatten_attribute , false },
116- { "target" , 1 , -1 , true, false, false,
117- d_handle_target_attribute , false },
118- { "noclone" , 0 , 0 , true, false, false,
119- d_handle_noclone_attribute , false },
120- { "section" , 1 , 1 , true, false, false,
121- d_handle_section_attribute , false },
122- { "alias" , 1 , 1 , true, false, false,
123- d_handle_alias_attribute , false },
124- { "weak" , 0 , 0 , true, false, false,
125- d_handle_weak_attribute , false },
126- { NULL , 0 , 0 , false, false, false, NULL , false }
147+ ATTR_SPEC ("noinline" , 0 , 0 , true, false, false, false,
148+ d_handle_noinline_attribute , attr_noinline_exclusions ),
149+ ATTR_SPEC ("forceinline" , 0 , 0 , true, false, false, false,
150+ d_handle_forceinline_attribute , attr_inline_exclusions ),
151+ ATTR_SPEC ("flatten" , 0 , 0 , true, false, false, false,
152+ d_handle_flatten_attribute , NULL ),
153+ ATTR_SPEC ("target" , 1 , -1 , true, false, false, false,
154+ d_handle_target_attribute , NULL ),
155+ ATTR_SPEC ("noclone" , 0 , 0 , true, false, false, false,
156+ d_handle_noclone_attribute , NULL ),
157+ ATTR_SPEC ("section" , 1 , 1 , true, false, false, false,
158+ d_handle_section_attribute , NULL ),
159+ ATTR_SPEC ("alias" , 1 , 1 , true, false, false, false,
160+ d_handle_alias_attribute , NULL ),
161+ ATTR_SPEC ("weak" , 0 , 0 , true, false, false, false,
162+ d_handle_weak_attribute , NULL ),
163+ ATTR_SPEC (NULL , 0 , 0 , false, false, false, false, NULL , NULL ),
127164};
128165
129166
@@ -539,25 +576,6 @@ handle_fnspec_attribute (tree *node ATTRIBUTE_UNUSED, tree ARG_UNUSED (name),
539576 return NULL_TREE ;
540577}
541578
542- /* Handle a "weakref" attribute; arguments as in struct
543- attribute_spec.handler. */
544-
545- static tree
546- handle_weakref_attribute (tree * node , tree ARG_UNUSED (name ),
547- tree ARG_UNUSED (args ), int ARG_UNUSED (flags ),
548- bool * no_add_attrs ATTRIBUTE_UNUSED )
549- {
550- gcc_assert (!decl_function_context (* node ));
551- gcc_assert (!lookup_attribute ("alias" , DECL_ATTRIBUTES (* node )));
552-
553- /* Can't call declare_weak because it wants this to be TREE_PUBLIC,
554- and that isn't supported; and because it wants to add it to
555- the list of weak decls, which isn't helpful. */
556- DECL_WEAK (* node ) = 1 ;
557-
558- return NULL_TREE ;
559- }
560-
561579/* Language specific attribute handlers. */
562580
563581/* Handle a "noinline" attribute. */
0 commit comments