d-attribs.cc revision 1.1.1.3 1 1.1 mrg /* d-attribs.c -- D attributes handling.
2 1.1.1.3 mrg Copyright (C) 2015-2022 Free Software Foundation, Inc.
3 1.1 mrg
4 1.1 mrg GCC is free software; you can redistribute it and/or modify
5 1.1 mrg it under the terms of the GNU General Public License as published by
6 1.1 mrg the Free Software Foundation; either version 3, or (at your option)
7 1.1 mrg any later version.
8 1.1 mrg
9 1.1 mrg GCC is distributed in the hope that it will be useful,
10 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
11 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 1.1 mrg GNU General Public License for more details.
13 1.1 mrg
14 1.1 mrg You should have received a copy of the GNU General Public License
15 1.1 mrg along with GCC; see the file COPYING3. If not see
16 1.1 mrg <http://www.gnu.org/licenses/>. */
17 1.1 mrg
18 1.1 mrg /* Implementation of attribute handlers for user defined attributes and
19 1.1 mrg internal built-in functions. */
20 1.1 mrg
21 1.1 mrg #include "config.h"
22 1.1 mrg #include "system.h"
23 1.1 mrg #include "coretypes.h"
24 1.1 mrg
25 1.1.1.2 mrg #include "dmd/attrib.h"
26 1.1 mrg #include "dmd/declaration.h"
27 1.1.1.3 mrg #include "dmd/expression.h"
28 1.1.1.3 mrg #include "dmd/module.h"
29 1.1 mrg #include "dmd/mtype.h"
30 1.1.1.3 mrg #include "dmd/template.h"
31 1.1 mrg
32 1.1 mrg #include "tree.h"
33 1.1 mrg #include "diagnostic.h"
34 1.1 mrg #include "tm.h"
35 1.1 mrg #include "cgraph.h"
36 1.1 mrg #include "toplev.h"
37 1.1 mrg #include "target.h"
38 1.1 mrg #include "common/common-target.h"
39 1.1 mrg #include "stringpool.h"
40 1.1 mrg #include "attribs.h"
41 1.1 mrg #include "varasm.h"
42 1.1.1.3 mrg #include "fold-const.h"
43 1.1.1.3 mrg #include "opts.h"
44 1.1 mrg
45 1.1 mrg #include "d-tree.h"
46 1.1 mrg
47 1.1 mrg
48 1.1 mrg /* Internal attribute handlers for built-in functions. */
49 1.1 mrg static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
50 1.1 mrg static tree handle_leaf_attribute (tree *, tree, tree, int, bool *);
51 1.1 mrg static tree handle_const_attribute (tree *, tree, tree, int, bool *);
52 1.1 mrg static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
53 1.1 mrg static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
54 1.1 mrg static tree handle_novops_attribute (tree *, tree, tree, int, bool *);
55 1.1 mrg static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
56 1.1 mrg static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
57 1.1 mrg static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
58 1.1 mrg static tree handle_transaction_pure_attribute (tree *, tree, tree, int, bool *);
59 1.1 mrg static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
60 1.1 mrg static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *);
61 1.1 mrg
62 1.1 mrg /* D attribute handlers for user defined attributes. */
63 1.1 mrg static tree d_handle_noinline_attribute (tree *, tree, tree, int, bool *);
64 1.1.1.3 mrg static tree d_handle_always_inline_attribute (tree *, tree, tree, int, bool *);
65 1.1 mrg static tree d_handle_flatten_attribute (tree *, tree, tree, int, bool *);
66 1.1 mrg static tree d_handle_target_attribute (tree *, tree, tree, int, bool *);
67 1.1.1.3 mrg static tree d_handle_target_clones_attribute (tree *, tree, tree, int, bool *);
68 1.1.1.3 mrg static tree d_handle_optimize_attribute (tree *, tree, tree, int, bool *);
69 1.1 mrg static tree d_handle_noclone_attribute (tree *, tree, tree, int, bool *);
70 1.1.1.3 mrg static tree d_handle_noicf_attribute (tree *, tree, tree, int, bool *);
71 1.1.1.3 mrg static tree d_handle_noipa_attribute (tree *, tree, tree, int, bool *);
72 1.1 mrg static tree d_handle_section_attribute (tree *, tree, tree, int, bool *);
73 1.1.1.3 mrg static tree d_handle_symver_attribute (tree *, tree, tree, int, bool *);
74 1.1 mrg static tree d_handle_weak_attribute (tree *, tree, tree, int, bool *) ;
75 1.1.1.3 mrg static tree d_handle_noplt_attribute (tree *, tree, tree, int, bool *) ;
76 1.1.1.3 mrg static tree d_handle_alloc_size_attribute (tree *, tree, tree, int, bool *);
77 1.1.1.3 mrg static tree d_handle_cold_attribute (tree *, tree, tree, int, bool *);
78 1.1.1.3 mrg static tree d_handle_restrict_attribute (tree *, tree, tree, int, bool *);
79 1.1.1.3 mrg static tree d_handle_used_attribute (tree *, tree, tree, int, bool *);
80 1.1 mrg
81 1.1 mrg /* Helper to define attribute exclusions. */
82 1.1 mrg #define ATTR_EXCL(name, function, type, variable) \
83 1.1 mrg { name, function, type, variable }
84 1.1 mrg
85 1.1 mrg /* Define attributes that are mutually exclusive with one another. */
86 1.1 mrg static const struct attribute_spec::exclusions attr_noreturn_exclusions[] =
87 1.1 mrg {
88 1.1.1.3 mrg ATTR_EXCL ("alloc_size", true, true, true),
89 1.1 mrg ATTR_EXCL ("const", true, true, true),
90 1.1 mrg ATTR_EXCL ("malloc", true, true, true),
91 1.1 mrg ATTR_EXCL ("pure", true, true, true),
92 1.1 mrg ATTR_EXCL ("returns_twice", true, true, true),
93 1.1 mrg ATTR_EXCL (NULL, false, false, false),
94 1.1 mrg };
95 1.1 mrg
96 1.1 mrg static const struct attribute_spec::exclusions attr_returns_twice_exclusions[] =
97 1.1 mrg {
98 1.1 mrg ATTR_EXCL ("noreturn", true, true, true),
99 1.1 mrg ATTR_EXCL (NULL, false, false, false),
100 1.1 mrg };
101 1.1 mrg
102 1.1 mrg static const struct attribute_spec::exclusions attr_const_pure_exclusions[] =
103 1.1 mrg {
104 1.1.1.3 mrg ATTR_EXCL ("alloc_size", true, true, true),
105 1.1 mrg ATTR_EXCL ("const", true, true, true),
106 1.1 mrg ATTR_EXCL ("noreturn", true, true, true),
107 1.1 mrg ATTR_EXCL ("pure", true, true, true),
108 1.1 mrg ATTR_EXCL (NULL, false, false, false)
109 1.1 mrg };
110 1.1 mrg
111 1.1 mrg static const struct attribute_spec::exclusions attr_inline_exclusions[] =
112 1.1 mrg {
113 1.1 mrg ATTR_EXCL ("noinline", true, true, true),
114 1.1.1.3 mrg ATTR_EXCL ("target_clones", true, true, true),
115 1.1 mrg ATTR_EXCL (NULL, false, false, false),
116 1.1 mrg };
117 1.1 mrg
118 1.1 mrg static const struct attribute_spec::exclusions attr_noinline_exclusions[] =
119 1.1 mrg {
120 1.1.1.3 mrg ATTR_EXCL ("always_inline", true, true, true),
121 1.1 mrg ATTR_EXCL (NULL, false, false, false),
122 1.1 mrg };
123 1.1 mrg
124 1.1.1.3 mrg static const struct attribute_spec::exclusions attr_target_exclusions[] =
125 1.1.1.3 mrg {
126 1.1.1.3 mrg ATTR_EXCL ("target_clones", true, true, true),
127 1.1.1.3 mrg ATTR_EXCL (NULL, false, false, false),
128 1.1.1.3 mrg };
129 1.1.1.3 mrg
130 1.1.1.3 mrg static const struct attribute_spec::exclusions attr_target_clones_exclusions[] =
131 1.1.1.3 mrg {
132 1.1.1.3 mrg ATTR_EXCL ("always_inline", true, true, true),
133 1.1.1.3 mrg ATTR_EXCL ("target", true, true, true),
134 1.1.1.3 mrg ATTR_EXCL (NULL, false, false, false),
135 1.1.1.3 mrg };
136 1.1.1.3 mrg
137 1.1.1.3 mrg static const struct attribute_spec::exclusions attr_alloc_exclusions[] =
138 1.1.1.3 mrg {
139 1.1.1.3 mrg ATTR_EXCL ("const", true, true, true),
140 1.1.1.3 mrg ATTR_EXCL ("noreturn", true, true, true),
141 1.1.1.3 mrg ATTR_EXCL ("pure", true, true, true),
142 1.1.1.3 mrg ATTR_EXCL (NULL, false, false, false),
143 1.1.1.3 mrg };
144 1.1.1.3 mrg
145 1.1.1.3 mrg extern const struct attribute_spec::exclusions attr_cold_hot_exclusions[] =
146 1.1.1.3 mrg {
147 1.1.1.3 mrg ATTR_EXCL ("cold", true, true, true),
148 1.1.1.3 mrg ATTR_EXCL ("hot", true, true, true),
149 1.1.1.3 mrg ATTR_EXCL (NULL, false, false, false)
150 1.1.1.3 mrg };
151 1.1.1.3 mrg
152 1.1 mrg /* Helper to define an attribute. */
153 1.1 mrg #define ATTR_SPEC(name, min_len, max_len, decl_req, type_req, fn_type_req, \
154 1.1 mrg affects_type_identity, handler, exclude) \
155 1.1 mrg { name, min_len, max_len, decl_req, type_req, fn_type_req, \
156 1.1 mrg affects_type_identity, handler, exclude }
157 1.1 mrg
158 1.1 mrg /* Table of machine-independent attributes.
159 1.1 mrg For internal use (marking of built-ins) only. */
160 1.1 mrg const attribute_spec d_langhook_common_attribute_table[] =
161 1.1 mrg {
162 1.1 mrg ATTR_SPEC ("noreturn", 0, 0, true, false, false, false,
163 1.1 mrg handle_noreturn_attribute, attr_noreturn_exclusions),
164 1.1 mrg ATTR_SPEC ("leaf", 0, 0, true, false, false, false,
165 1.1 mrg handle_leaf_attribute, NULL),
166 1.1 mrg ATTR_SPEC ("const", 0, 0, true, false, false, false,
167 1.1 mrg handle_const_attribute, attr_const_pure_exclusions),
168 1.1 mrg ATTR_SPEC ("malloc", 0, 0, true, false, false, false,
169 1.1 mrg handle_malloc_attribute, NULL),
170 1.1 mrg ATTR_SPEC ("returns_twice", 0, 0, true, false, false, false,
171 1.1 mrg handle_returns_twice_attribute, attr_returns_twice_exclusions),
172 1.1 mrg ATTR_SPEC ("pure", 0, 0, true, false, false, false,
173 1.1 mrg handle_pure_attribute, attr_const_pure_exclusions),
174 1.1 mrg ATTR_SPEC ("nonnull", 0, -1, false, true, true, false,
175 1.1 mrg handle_nonnull_attribute, NULL),
176 1.1 mrg ATTR_SPEC ("nothrow", 0, 0, true, false, false, false,
177 1.1 mrg handle_nothrow_attribute, NULL),
178 1.1 mrg ATTR_SPEC ("transaction_pure", 0, 0, false, true, true, false,
179 1.1 mrg handle_transaction_pure_attribute, NULL),
180 1.1 mrg ATTR_SPEC ("no vops", 0, 0, true, false, false, false,
181 1.1 mrg handle_novops_attribute, NULL),
182 1.1 mrg ATTR_SPEC ("type generic", 0, 0, false, true, true, false,
183 1.1 mrg handle_type_generic_attribute, NULL),
184 1.1 mrg ATTR_SPEC ("fn spec", 1, 1, false, true, true, false,
185 1.1 mrg handle_fnspec_attribute, NULL),
186 1.1 mrg ATTR_SPEC (NULL, 0, 0, false, false, false, false, NULL, NULL),
187 1.1 mrg };
188 1.1 mrg
189 1.1 mrg /* Table of D language attributes exposed by `gcc.attribute' UDAs. */
190 1.1 mrg const attribute_spec d_langhook_attribute_table[] =
191 1.1 mrg {
192 1.1 mrg ATTR_SPEC ("noinline", 0, 0, true, false, false, false,
193 1.1 mrg d_handle_noinline_attribute, attr_noinline_exclusions),
194 1.1.1.3 mrg ATTR_SPEC ("always_inline", 0, 0, true, false, false, false,
195 1.1.1.3 mrg d_handle_always_inline_attribute, attr_inline_exclusions),
196 1.1 mrg ATTR_SPEC ("flatten", 0, 0, true, false, false, false,
197 1.1 mrg d_handle_flatten_attribute, NULL),
198 1.1 mrg ATTR_SPEC ("target", 1, -1, true, false, false, false,
199 1.1.1.3 mrg d_handle_target_attribute, attr_target_exclusions),
200 1.1.1.3 mrg ATTR_SPEC ("target_clones", 1, -1, true, false, false, false,
201 1.1.1.3 mrg d_handle_target_clones_attribute, attr_target_clones_exclusions),
202 1.1.1.3 mrg ATTR_SPEC ("optimize", 1, -1, true, false, false, false,
203 1.1.1.3 mrg d_handle_optimize_attribute, NULL),
204 1.1 mrg ATTR_SPEC ("noclone", 0, 0, true, false, false, false,
205 1.1 mrg d_handle_noclone_attribute, NULL),
206 1.1.1.3 mrg ATTR_SPEC ("no_icf", 0, 0, true, false, false, false,
207 1.1.1.3 mrg d_handle_noicf_attribute, NULL),
208 1.1.1.3 mrg ATTR_SPEC ("noipa", 0, 0, true, false, false, false,
209 1.1.1.3 mrg d_handle_noipa_attribute, NULL),
210 1.1 mrg ATTR_SPEC ("section", 1, 1, true, false, false, false,
211 1.1 mrg d_handle_section_attribute, NULL),
212 1.1.1.3 mrg ATTR_SPEC ("symver", 1, -1, true, false, false, false,
213 1.1.1.3 mrg d_handle_symver_attribute, NULL),
214 1.1 mrg ATTR_SPEC ("weak", 0, 0, true, false, false, false,
215 1.1 mrg d_handle_weak_attribute, NULL),
216 1.1.1.3 mrg ATTR_SPEC ("noplt", 0, 0, true, false, false, false,
217 1.1.1.3 mrg d_handle_noplt_attribute, NULL),
218 1.1.1.3 mrg ATTR_SPEC ("alloc_size", 1, 3, false, true, true, false,
219 1.1.1.3 mrg d_handle_alloc_size_attribute, attr_alloc_exclusions),
220 1.1.1.3 mrg ATTR_SPEC ("cold", 0, 0, true, false, false, false,
221 1.1.1.3 mrg d_handle_cold_attribute, attr_cold_hot_exclusions),
222 1.1.1.3 mrg ATTR_SPEC ("restrict", 0, 0, true, false, false, false,
223 1.1.1.3 mrg d_handle_restrict_attribute, NULL),
224 1.1.1.3 mrg ATTR_SPEC ("used", 0, 0, true, false, false, false,
225 1.1.1.3 mrg d_handle_used_attribute, NULL),
226 1.1 mrg ATTR_SPEC (NULL, 0, 0, false, false, false, false, NULL, NULL),
227 1.1 mrg };
228 1.1 mrg
229 1.1 mrg
230 1.1 mrg /* Insert the type attribute ATTRNAME with value VALUE into TYPE.
231 1.1 mrg Returns a new variant of the original type declaration. */
232 1.1 mrg
233 1.1 mrg tree
234 1.1 mrg insert_type_attribute (tree type, const char *attrname, tree value)
235 1.1 mrg {
236 1.1 mrg tree ident = get_identifier (attrname);
237 1.1 mrg
238 1.1 mrg if (value)
239 1.1 mrg value = tree_cons (NULL_TREE, value, NULL_TREE);
240 1.1 mrg
241 1.1 mrg tree attribs = merge_attributes (TYPE_ATTRIBUTES (type),
242 1.1 mrg tree_cons (ident, value, NULL_TREE));
243 1.1 mrg
244 1.1 mrg return build_type_attribute_variant (type, attribs);
245 1.1 mrg }
246 1.1 mrg
247 1.1 mrg /* Insert the decl attribute ATTRNAME with value VALUE into DECL. */
248 1.1 mrg
249 1.1 mrg tree
250 1.1 mrg insert_decl_attribute (tree decl, const char *attrname, tree value)
251 1.1 mrg {
252 1.1 mrg tree ident = get_identifier (attrname);
253 1.1 mrg
254 1.1 mrg if (value)
255 1.1 mrg value = tree_cons (NULL_TREE, value, NULL_TREE);
256 1.1 mrg
257 1.1 mrg tree attribs = merge_attributes (DECL_ATTRIBUTES (decl),
258 1.1 mrg tree_cons (ident, value, NULL_TREE));
259 1.1 mrg
260 1.1 mrg return build_decl_attribute_variant (decl, attribs);
261 1.1 mrg }
262 1.1 mrg
263 1.1 mrg /* Returns TRUE if NAME is an attribute recognized as being handled by
264 1.1 mrg the `gcc.attribute' module. */
265 1.1 mrg
266 1.1 mrg static bool
267 1.1 mrg uda_attribute_p (const char *name)
268 1.1 mrg {
269 1.1 mrg tree ident = get_identifier (name);
270 1.1 mrg
271 1.1 mrg /* Search both our language, and target attribute tables.
272 1.1 mrg Common and format attributes are kept internal. */
273 1.1 mrg for (const attribute_spec *p = d_langhook_attribute_table; p->name; p++)
274 1.1 mrg {
275 1.1 mrg if (get_identifier (p->name) == ident)
276 1.1 mrg return true;
277 1.1 mrg }
278 1.1 mrg
279 1.1.1.2 mrg if (targetm.attribute_table)
280 1.1 mrg {
281 1.1.1.2 mrg for (const attribute_spec *p = targetm.attribute_table; p->name; p++)
282 1.1.1.2 mrg {
283 1.1.1.2 mrg if (get_identifier (p->name) == ident)
284 1.1.1.2 mrg return true;
285 1.1.1.2 mrg }
286 1.1 mrg }
287 1.1 mrg
288 1.1 mrg return false;
289 1.1 mrg }
290 1.1 mrg
291 1.1 mrg /* [attribute/uda]
292 1.1 mrg
293 1.1 mrg User Defined Attributes (UDA) are compile time expressions that can be
294 1.1 mrg attached to a declaration. These attributes can then be queried, extracted,
295 1.1 mrg and manipulated at compile-time. There is no run-time component to them.
296 1.1 mrg
297 1.1 mrg Expand and merge all UDAs found in the EATTRS list that are of type
298 1.1 mrg `gcc.attribute.Attribute'. This symbol is internally recognized by the
299 1.1 mrg compiler and maps them to their equivalent GCC attribute. */
300 1.1 mrg
301 1.1.1.2 mrg static tree
302 1.1 mrg build_attributes (Expressions *eattrs)
303 1.1 mrg {
304 1.1 mrg if (!eattrs)
305 1.1 mrg return NULL_TREE;
306 1.1 mrg
307 1.1 mrg expandTuples (eattrs);
308 1.1 mrg
309 1.1 mrg tree attribs = NULL_TREE;
310 1.1 mrg
311 1.1.1.3 mrg for (size_t i = 0; i < eattrs->length; i++)
312 1.1 mrg {
313 1.1 mrg Expression *attr = (*eattrs)[i];
314 1.1 mrg Dsymbol *sym = attr->type->toDsymbol (0);
315 1.1 mrg
316 1.1 mrg if (!sym)
317 1.1.1.3 mrg {
318 1.1.1.3 mrg /* If attribute is a template symbol, perhaps arguments were not
319 1.1.1.3 mrg supplied, so warn about attribute having no effect. */
320 1.1.1.3 mrg if (TemplateExp *te = attr->isTemplateExp ())
321 1.1.1.3 mrg {
322 1.1.1.3 mrg if (!te->td || !te->td->onemember)
323 1.1.1.3 mrg continue;
324 1.1.1.3 mrg
325 1.1.1.3 mrg sym = te->td->onemember;
326 1.1.1.3 mrg }
327 1.1.1.3 mrg else
328 1.1.1.3 mrg continue;
329 1.1.1.3 mrg }
330 1.1 mrg
331 1.1 mrg /* Attribute symbol must come from the `gcc.attribute' module. */
332 1.1.1.3 mrg Dsymbol *mod = sym->getModule ();
333 1.1.1.3 mrg if (!(strcmp (mod->toChars (), "attributes") == 0
334 1.1 mrg && mod->parent != NULL
335 1.1 mrg && strcmp (mod->parent->toChars (), "gcc") == 0
336 1.1 mrg && !mod->parent->parent))
337 1.1 mrg continue;
338 1.1 mrg
339 1.1 mrg /* Get the result of the attribute if it hasn't already been folded. */
340 1.1.1.3 mrg if (attr->op == EXP::call)
341 1.1 mrg attr = attr->ctfeInterpret ();
342 1.1 mrg
343 1.1.1.3 mrg if (attr->op != EXP::structLiteral)
344 1.1.1.3 mrg {
345 1.1.1.3 mrg warning_at (make_location_t (attr->loc), OPT_Wattributes,
346 1.1.1.3 mrg "%qE attribute has no effect",
347 1.1.1.3 mrg get_identifier (sym->toChars ()));
348 1.1.1.3 mrg continue;
349 1.1.1.3 mrg }
350 1.1.1.3 mrg
351 1.1 mrg /* Should now have a struct `Attribute("attrib", "value", ...)'
352 1.1 mrg initializer list. */
353 1.1.1.3 mrg Expressions *elems = attr->isStructLiteralExp ()->elements;
354 1.1 mrg Expression *e0 = (*elems)[0];
355 1.1 mrg
356 1.1.1.3 mrg if (e0->op != EXP::string_)
357 1.1 mrg {
358 1.1.1.3 mrg warning_at (make_location_t (attr->loc), OPT_Wattributes,
359 1.1.1.3 mrg "unknown attribute %qs", e0->toChars());
360 1.1.1.3 mrg continue;
361 1.1 mrg }
362 1.1 mrg
363 1.1.1.3 mrg StringExp *se = e0->toStringExp ();
364 1.1 mrg gcc_assert (se->sz == 1);
365 1.1 mrg
366 1.1 mrg /* Empty string attribute, just ignore it. */
367 1.1 mrg if (se->len == 0)
368 1.1 mrg continue;
369 1.1 mrg
370 1.1 mrg /* Check if the attribute is recognized and handled.
371 1.1 mrg Done here to report the diagnostic at the right location. */
372 1.1 mrg const char *name = (const char *)(se->len ? se->string : "");
373 1.1 mrg if (!uda_attribute_p (name))
374 1.1 mrg {
375 1.1.1.3 mrg warning_at (make_location_t (attr->loc), OPT_Wattributes,
376 1.1 mrg "unknown attribute %qs", name);
377 1.1.1.3 mrg continue;
378 1.1 mrg }
379 1.1 mrg
380 1.1 mrg /* Chain all attribute arguments together. */
381 1.1 mrg tree args = NULL_TREE;
382 1.1 mrg
383 1.1.1.3 mrg for (size_t j = 1; j < elems->length; j++)
384 1.1 mrg {
385 1.1 mrg Expression *e = (*elems)[j];
386 1.1.1.3 mrg /* Stop after the first `void' argument. */
387 1.1.1.3 mrg if (e == NULL)
388 1.1.1.3 mrg break;
389 1.1.1.3 mrg
390 1.1.1.3 mrg StringExp *s = e->isStringExp ();
391 1.1 mrg tree t;
392 1.1.1.3 mrg if (s != NULL && s->sz == 1)
393 1.1 mrg {
394 1.1 mrg const char *string = (const char *)(s->len ? s->string : "");
395 1.1 mrg t = build_string (s->len, string);
396 1.1 mrg }
397 1.1 mrg else
398 1.1 mrg t = build_expr (e);
399 1.1 mrg
400 1.1 mrg args = chainon (args, build_tree_list (0, t));
401 1.1 mrg }
402 1.1 mrg
403 1.1 mrg tree list = build_tree_list (get_identifier (name), args);
404 1.1 mrg attribs = chainon (attribs, list);
405 1.1 mrg }
406 1.1 mrg
407 1.1 mrg return attribs;
408 1.1 mrg }
409 1.1 mrg
410 1.1.1.2 mrg /* If any GCC attributes are found in the declaration SYM, apply them to the
411 1.1.1.2 mrg type or decl NODE. */
412 1.1.1.2 mrg
413 1.1.1.2 mrg void
414 1.1.1.2 mrg apply_user_attributes (Dsymbol *sym, tree node)
415 1.1.1.2 mrg {
416 1.1.1.2 mrg if (!sym->userAttribDecl)
417 1.1.1.2 mrg {
418 1.1.1.2 mrg if (DECL_P (node) && DECL_ATTRIBUTES (node) != NULL)
419 1.1.1.2 mrg decl_attributes (&node, DECL_ATTRIBUTES (node), 0);
420 1.1.1.2 mrg
421 1.1.1.2 mrg return;
422 1.1.1.2 mrg }
423 1.1.1.2 mrg
424 1.1.1.2 mrg location_t saved_location = input_location;
425 1.1.1.2 mrg input_location = make_location_t (sym->loc);
426 1.1.1.2 mrg
427 1.1.1.2 mrg Expressions *attrs = sym->userAttribDecl->getAttributes ();
428 1.1.1.2 mrg decl_attributes (&node, build_attributes (attrs),
429 1.1.1.2 mrg TYPE_P (node) ? ATTR_FLAG_TYPE_IN_PLACE : 0);
430 1.1.1.2 mrg
431 1.1.1.2 mrg input_location = saved_location;
432 1.1.1.2 mrg }
433 1.1.1.2 mrg
434 1.1.1.3 mrg /* Built-in attribute handlers.
435 1.1.1.3 mrg These functions take the arguments:
436 1.1.1.3 mrg (tree *node, tree name, tree args, int flags, bool *no_add_attrs) */
437 1.1 mrg
438 1.1 mrg /* Handle a "noreturn" attribute; arguments as in
439 1.1 mrg struct attribute_spec.handler. */
440 1.1 mrg
441 1.1 mrg static tree
442 1.1.1.3 mrg handle_noreturn_attribute (tree *node, tree, tree, int, bool *)
443 1.1 mrg {
444 1.1 mrg tree type = TREE_TYPE (*node);
445 1.1 mrg
446 1.1 mrg if (TREE_CODE (*node) == FUNCTION_DECL)
447 1.1 mrg TREE_THIS_VOLATILE (*node) = 1;
448 1.1 mrg else if (TREE_CODE (type) == POINTER_TYPE
449 1.1 mrg && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
450 1.1 mrg TREE_TYPE (*node)
451 1.1 mrg = build_pointer_type
452 1.1 mrg (build_type_variant (TREE_TYPE (type),
453 1.1 mrg TYPE_READONLY (TREE_TYPE (type)), 1));
454 1.1 mrg else
455 1.1 mrg gcc_unreachable ();
456 1.1 mrg
457 1.1 mrg return NULL_TREE;
458 1.1 mrg }
459 1.1 mrg
460 1.1 mrg /* Handle a "leaf" attribute; arguments as in
461 1.1 mrg struct attribute_spec.handler. */
462 1.1 mrg
463 1.1 mrg static tree
464 1.1.1.3 mrg handle_leaf_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
465 1.1 mrg {
466 1.1 mrg if (TREE_CODE (*node) != FUNCTION_DECL)
467 1.1 mrg {
468 1.1 mrg warning (OPT_Wattributes, "%qE attribute ignored", name);
469 1.1 mrg *no_add_attrs = true;
470 1.1 mrg }
471 1.1 mrg if (!TREE_PUBLIC (*node))
472 1.1 mrg {
473 1.1 mrg warning (OPT_Wattributes, "%qE attribute has no effect", name);
474 1.1 mrg *no_add_attrs = true;
475 1.1 mrg }
476 1.1 mrg
477 1.1 mrg return NULL_TREE;
478 1.1 mrg }
479 1.1 mrg
480 1.1 mrg /* Handle a "const" attribute; arguments as in
481 1.1 mrg struct attribute_spec.handler. */
482 1.1 mrg
483 1.1 mrg static tree
484 1.1.1.3 mrg handle_const_attribute (tree *node, tree, tree, int, bool *)
485 1.1 mrg {
486 1.1 mrg tree type = TREE_TYPE (*node);
487 1.1 mrg
488 1.1 mrg if (TREE_CODE (*node) == FUNCTION_DECL)
489 1.1 mrg TREE_READONLY (*node) = 1;
490 1.1 mrg else if (TREE_CODE (type) == POINTER_TYPE
491 1.1 mrg && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
492 1.1 mrg TREE_TYPE (*node)
493 1.1 mrg = build_pointer_type
494 1.1 mrg (build_type_variant (TREE_TYPE (type), 1,
495 1.1 mrg TREE_THIS_VOLATILE (TREE_TYPE (type))));
496 1.1 mrg else
497 1.1 mrg gcc_unreachable ();
498 1.1 mrg
499 1.1 mrg return NULL_TREE;
500 1.1 mrg }
501 1.1 mrg
502 1.1 mrg /* Handle a "malloc" attribute; arguments as in
503 1.1 mrg struct attribute_spec.handler. */
504 1.1 mrg
505 1.1 mrg tree
506 1.1.1.3 mrg handle_malloc_attribute (tree *node, tree, tree, int, bool *)
507 1.1 mrg {
508 1.1 mrg gcc_assert (TREE_CODE (*node) == FUNCTION_DECL
509 1.1 mrg && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node))));
510 1.1 mrg DECL_IS_MALLOC (*node) = 1;
511 1.1 mrg return NULL_TREE;
512 1.1 mrg }
513 1.1 mrg
514 1.1 mrg /* Handle a "pure" attribute; arguments as in
515 1.1 mrg struct attribute_spec.handler. */
516 1.1 mrg
517 1.1 mrg static tree
518 1.1.1.3 mrg handle_pure_attribute (tree *node, tree, tree, int, bool *)
519 1.1 mrg {
520 1.1 mrg gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
521 1.1 mrg DECL_PURE_P (*node) = 1;
522 1.1 mrg return NULL_TREE;
523 1.1 mrg }
524 1.1 mrg
525 1.1 mrg /* Handle a "no vops" attribute; arguments as in
526 1.1 mrg struct attribute_spec.handler. */
527 1.1 mrg
528 1.1 mrg static tree
529 1.1.1.3 mrg handle_novops_attribute (tree *node, tree, tree, int, bool *)
530 1.1 mrg {
531 1.1 mrg gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
532 1.1 mrg DECL_IS_NOVOPS (*node) = 1;
533 1.1 mrg return NULL_TREE;
534 1.1 mrg }
535 1.1 mrg
536 1.1 mrg /* Helper for nonnull attribute handling; fetch the operand number
537 1.1 mrg from the attribute argument list. */
538 1.1 mrg
539 1.1 mrg static bool
540 1.1 mrg get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp)
541 1.1 mrg {
542 1.1 mrg /* Verify the arg number is a constant. */
543 1.1 mrg if (!tree_fits_uhwi_p (arg_num_expr))
544 1.1 mrg return false;
545 1.1 mrg
546 1.1 mrg *valp = TREE_INT_CST_LOW (arg_num_expr);
547 1.1 mrg return true;
548 1.1 mrg }
549 1.1 mrg
550 1.1 mrg /* Handle the "nonnull" attribute. */
551 1.1 mrg
552 1.1 mrg static tree
553 1.1.1.3 mrg handle_nonnull_attribute (tree *node, tree, tree args, int, bool *)
554 1.1 mrg {
555 1.1 mrg tree type = *node;
556 1.1 mrg
557 1.1 mrg /* If no arguments are specified, all pointer arguments should be
558 1.1 mrg non-null. Verify a full prototype is given so that the arguments
559 1.1 mrg will have the correct types when we actually check them later.
560 1.1 mrg Avoid diagnosing type-generic built-ins since those have no
561 1.1 mrg prototype. */
562 1.1 mrg if (!args)
563 1.1 mrg {
564 1.1 mrg gcc_assert (prototype_p (type)
565 1.1 mrg || !TYPE_ATTRIBUTES (type)
566 1.1 mrg || lookup_attribute ("type generic", TYPE_ATTRIBUTES (type)));
567 1.1 mrg
568 1.1 mrg return NULL_TREE;
569 1.1 mrg }
570 1.1 mrg
571 1.1 mrg /* Argument list specified. Verify that each argument number references
572 1.1 mrg a pointer argument. */
573 1.1 mrg for (; args; args = TREE_CHAIN (args))
574 1.1 mrg {
575 1.1 mrg tree argument;
576 1.1 mrg unsigned HOST_WIDE_INT arg_num = 0, ck_num;
577 1.1 mrg
578 1.1 mrg if (!get_nonnull_operand (TREE_VALUE (args), &arg_num))
579 1.1 mrg gcc_unreachable ();
580 1.1 mrg
581 1.1 mrg argument = TYPE_ARG_TYPES (type);
582 1.1 mrg if (argument)
583 1.1 mrg {
584 1.1 mrg for (ck_num = 1; ; ck_num++)
585 1.1 mrg {
586 1.1 mrg if (!argument || ck_num == arg_num)
587 1.1 mrg break;
588 1.1 mrg argument = TREE_CHAIN (argument);
589 1.1 mrg }
590 1.1 mrg
591 1.1 mrg gcc_assert (argument
592 1.1 mrg && TREE_CODE (TREE_VALUE (argument)) == POINTER_TYPE);
593 1.1 mrg }
594 1.1 mrg }
595 1.1 mrg
596 1.1 mrg return NULL_TREE;
597 1.1 mrg }
598 1.1 mrg
599 1.1 mrg /* Handle a "nothrow" attribute; arguments as in
600 1.1 mrg struct attribute_spec.handler. */
601 1.1 mrg
602 1.1 mrg static tree
603 1.1.1.3 mrg handle_nothrow_attribute (tree *node, tree, tree, int, bool *)
604 1.1 mrg {
605 1.1 mrg gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
606 1.1 mrg TREE_NOTHROW (*node) = 1;
607 1.1 mrg return NULL_TREE;
608 1.1 mrg }
609 1.1 mrg
610 1.1.1.3 mrg /* Handle a "type generic" attribute; arguments as in
611 1.1.1.3 mrg struct attribute_spec.handler. */
612 1.1 mrg
613 1.1 mrg static tree
614 1.1.1.3 mrg handle_type_generic_attribute (tree *node, tree, tree, int, bool *)
615 1.1 mrg {
616 1.1 mrg /* Ensure we have a function type. */
617 1.1 mrg gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
618 1.1 mrg
619 1.1 mrg /* Ensure we have a variadic function. */
620 1.1 mrg gcc_assert (!prototype_p (*node) || stdarg_p (*node));
621 1.1 mrg
622 1.1 mrg return NULL_TREE;
623 1.1 mrg }
624 1.1 mrg
625 1.1.1.3 mrg /* Handle a "transaction_pure" attribute; arguments as in
626 1.1.1.3 mrg struct attribute_spec.handler. */
627 1.1 mrg
628 1.1 mrg static tree
629 1.1.1.3 mrg handle_transaction_pure_attribute (tree *node, tree, tree, int, bool *)
630 1.1 mrg {
631 1.1 mrg /* Ensure we have a function type. */
632 1.1 mrg gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
633 1.1 mrg
634 1.1 mrg return NULL_TREE;
635 1.1 mrg }
636 1.1 mrg
637 1.1.1.3 mrg /* Handle a "returns_twice" attribute; arguments as in
638 1.1.1.3 mrg struct attribute_spec.handler. */
639 1.1 mrg
640 1.1 mrg static tree
641 1.1.1.3 mrg handle_returns_twice_attribute (tree *node, tree, tree, int, bool *)
642 1.1 mrg {
643 1.1 mrg gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
644 1.1 mrg
645 1.1 mrg DECL_IS_RETURNS_TWICE (*node) = 1;
646 1.1 mrg
647 1.1 mrg return NULL_TREE;
648 1.1 mrg }
649 1.1 mrg
650 1.1 mrg /* Handle a "fn spec" attribute; arguments as in
651 1.1 mrg struct attribute_spec.handler. */
652 1.1 mrg
653 1.1 mrg tree
654 1.1.1.3 mrg handle_fnspec_attribute (tree *, tree, tree args, int, bool *)
655 1.1 mrg {
656 1.1 mrg gcc_assert (args
657 1.1 mrg && TREE_CODE (TREE_VALUE (args)) == STRING_CST
658 1.1 mrg && !TREE_CHAIN (args));
659 1.1 mrg return NULL_TREE;
660 1.1 mrg }
661 1.1 mrg
662 1.1.1.3 mrg /* Language specific attribute handlers.
663 1.1.1.3 mrg These functions take the arguments:
664 1.1.1.3 mrg (tree *node, tree name, tree args, int flags, bool *no_add_attrs) */
665 1.1 mrg
666 1.1.1.3 mrg /* Handle a "noinline" attribute; arguments as in
667 1.1.1.3 mrg struct attribute_spec.handler. */
668 1.1 mrg
669 1.1 mrg static tree
670 1.1.1.3 mrg d_handle_noinline_attribute (tree *node, tree name, tree, int,
671 1.1.1.3 mrg bool *no_add_attrs)
672 1.1 mrg {
673 1.1.1.3 mrg if (TREE_CODE (*node) == FUNCTION_DECL)
674 1.1 mrg DECL_UNINLINABLE (*node) = 1;
675 1.1 mrg else
676 1.1 mrg {
677 1.1 mrg warning (OPT_Wattributes, "%qE attribute ignored", name);
678 1.1 mrg *no_add_attrs = true;
679 1.1 mrg }
680 1.1 mrg
681 1.1 mrg return NULL_TREE;
682 1.1 mrg }
683 1.1 mrg
684 1.1.1.3 mrg /* Handle a "always_inline" attribute; arguments as in
685 1.1.1.3 mrg struct attribute_spec.handler. */
686 1.1 mrg
687 1.1 mrg static tree
688 1.1.1.3 mrg d_handle_always_inline_attribute (tree *node, tree name, tree, int,
689 1.1.1.3 mrg bool *no_add_attrs)
690 1.1 mrg {
691 1.1.1.3 mrg if (TREE_CODE (*node) == FUNCTION_DECL)
692 1.1 mrg {
693 1.1 mrg DECL_DECLARED_INLINE_P (*node) = 1;
694 1.1 mrg DECL_DISREGARD_INLINE_LIMITS (*node) = 1;
695 1.1 mrg }
696 1.1 mrg else
697 1.1 mrg {
698 1.1 mrg warning (OPT_Wattributes, "%qE attribute ignored", name);
699 1.1 mrg *no_add_attrs = true;
700 1.1 mrg }
701 1.1 mrg
702 1.1 mrg return NULL_TREE;
703 1.1 mrg }
704 1.1 mrg
705 1.1.1.3 mrg /* Handle a "flatten" attribute; arguments as in
706 1.1.1.3 mrg struct attribute_spec.handler. */
707 1.1 mrg
708 1.1 mrg static tree
709 1.1.1.3 mrg d_handle_flatten_attribute (tree *node, tree name, tree, int,
710 1.1.1.3 mrg bool *no_add_attrs)
711 1.1 mrg {
712 1.1.1.3 mrg if (TREE_CODE (*node) != FUNCTION_DECL)
713 1.1 mrg {
714 1.1 mrg warning (OPT_Wattributes, "%qE attribute ignored", name);
715 1.1 mrg *no_add_attrs = true;
716 1.1 mrg }
717 1.1 mrg
718 1.1 mrg return NULL_TREE;
719 1.1 mrg }
720 1.1 mrg
721 1.1.1.3 mrg /* Handle a "target" attribute; arguments as in
722 1.1.1.3 mrg struct attribute_spec.handler. */
723 1.1 mrg
724 1.1 mrg static tree
725 1.1 mrg d_handle_target_attribute (tree *node, tree name, tree args, int flags,
726 1.1 mrg bool *no_add_attrs)
727 1.1 mrg {
728 1.1 mrg /* Ensure we have a function type. */
729 1.1.1.3 mrg if (TREE_CODE (*node) != FUNCTION_DECL)
730 1.1 mrg {
731 1.1 mrg warning (OPT_Wattributes, "%qE attribute ignored", name);
732 1.1 mrg *no_add_attrs = true;
733 1.1 mrg }
734 1.1.1.3 mrg else if (!targetm.target_option.valid_attribute_p (*node, name, args, flags))
735 1.1 mrg *no_add_attrs = true;
736 1.1 mrg
737 1.1.1.3 mrg /* Check that there's no empty string in values of the attribute. */
738 1.1.1.3 mrg for (tree t = args; t != NULL_TREE; t = TREE_CHAIN (t))
739 1.1.1.3 mrg {
740 1.1.1.3 mrg tree value = TREE_VALUE (t);
741 1.1.1.3 mrg if (TREE_CODE (value) != STRING_CST
742 1.1.1.3 mrg || (TREE_STRING_LENGTH (value) != 0
743 1.1.1.3 mrg && TREE_STRING_POINTER (value)[0] != '\0'))
744 1.1.1.3 mrg continue;
745 1.1.1.3 mrg
746 1.1.1.3 mrg warning (OPT_Wattributes, "empty string in attribute %<target%>");
747 1.1.1.3 mrg *no_add_attrs = true;
748 1.1.1.3 mrg }
749 1.1.1.3 mrg
750 1.1 mrg return NULL_TREE;
751 1.1 mrg }
752 1.1 mrg
753 1.1.1.3 mrg /* Handle a "target_clones" attribute; arguments as in
754 1.1.1.3 mrg struct attribute_spec.handler. */
755 1.1 mrg
756 1.1 mrg static tree
757 1.1.1.3 mrg d_handle_target_clones_attribute (tree *node, tree name, tree, int,
758 1.1.1.3 mrg bool *no_add_attrs)
759 1.1 mrg {
760 1.1.1.3 mrg /* Ensure we have a function type. */
761 1.1.1.3 mrg if (TREE_CODE (*node) != FUNCTION_DECL)
762 1.1 mrg {
763 1.1.1.3 mrg warning (OPT_Wattributes, "%qE attribute ignored", name);
764 1.1.1.3 mrg *no_add_attrs = true;
765 1.1 mrg }
766 1.1 mrg else
767 1.1 mrg {
768 1.1.1.3 mrg /* Do not inline functions with multiple clone targets. */
769 1.1.1.3 mrg DECL_UNINLINABLE (*node) = 1;
770 1.1 mrg }
771 1.1 mrg
772 1.1 mrg return NULL_TREE;
773 1.1 mrg }
774 1.1 mrg
775 1.1.1.3 mrg /* Arguments being collected for optimization. */
776 1.1.1.3 mrg static GTY(()) vec <const char *, va_gc> *optimize_args;
777 1.1 mrg
778 1.1.1.3 mrg /* Inner function to convert a TREE_LIST to argv string to parse the optimize
779 1.1.1.3 mrg options in ARGS. */
780 1.1.1.3 mrg
781 1.1.1.3 mrg static bool
782 1.1.1.3 mrg parse_optimize_options (tree args)
783 1.1 mrg {
784 1.1.1.3 mrg bool ret = true;
785 1.1 mrg
786 1.1.1.3 mrg /* Build up argv vector. Just in case the string is stored away, use garbage
787 1.1.1.3 mrg collected strings. */
788 1.1.1.3 mrg vec_safe_truncate (optimize_args, 0);
789 1.1.1.3 mrg vec_safe_push (optimize_args, (const char *) NULL);
790 1.1.1.3 mrg
791 1.1.1.3 mrg for (tree ap = args; ap != NULL_TREE; ap = TREE_CHAIN (ap))
792 1.1 mrg {
793 1.1.1.3 mrg tree value = TREE_VALUE (ap);
794 1.1.1.3 mrg
795 1.1.1.3 mrg if (TREE_CODE (value) == INTEGER_CST)
796 1.1 mrg {
797 1.1.1.3 mrg char buffer[20];
798 1.1.1.3 mrg sprintf (buffer, "-O%ld", (long) TREE_INT_CST_LOW (value));
799 1.1.1.3 mrg vec_safe_push (optimize_args, ggc_strdup (buffer));
800 1.1.1.3 mrg }
801 1.1.1.3 mrg else if (TREE_CODE (value) == STRING_CST)
802 1.1.1.3 mrg {
803 1.1.1.3 mrg size_t len = TREE_STRING_LENGTH (value);
804 1.1.1.3 mrg const char *p = TREE_STRING_POINTER (value);
805 1.1 mrg
806 1.1.1.3 mrg /* If the user supplied -Oxxx or -fxxx, only allow -Oxxx or -fxxx
807 1.1.1.3 mrg options. */
808 1.1.1.3 mrg if (*p == '-' && p[1] != 'O' && p[1] != 'f')
809 1.1 mrg {
810 1.1.1.3 mrg ret = false;
811 1.1.1.3 mrg warning (OPT_Wattributes,
812 1.1.1.3 mrg "bad option %qs to attribute %<optimize%>", p);
813 1.1.1.3 mrg continue;
814 1.1 mrg }
815 1.1.1.3 mrg
816 1.1.1.3 mrg /* Can't use GC memory here. */
817 1.1.1.3 mrg char *q = XOBNEWVEC (&opts_obstack, char, len + 3);
818 1.1.1.3 mrg char *r = q;
819 1.1.1.3 mrg
820 1.1.1.3 mrg if (*p != '-')
821 1.1 mrg {
822 1.1.1.3 mrg *r++ = '-';
823 1.1.1.3 mrg
824 1.1.1.3 mrg /* Assume that Ox is -Ox, a numeric value is -Ox, a s by
825 1.1.1.3 mrg itself is -Os, and any other switch begins with a -f. */
826 1.1.1.3 mrg if ((*p >= '0' && *p <= '9') || (p[0] == 's' && p[1] == '\0'))
827 1.1.1.3 mrg *r++ = 'O';
828 1.1.1.3 mrg else if (*p != 'O')
829 1.1.1.3 mrg *r++ = 'f';
830 1.1 mrg }
831 1.1.1.3 mrg
832 1.1.1.3 mrg memcpy (r, p, len);
833 1.1.1.3 mrg r[len] = '\0';
834 1.1.1.3 mrg vec_safe_push (optimize_args, (const char *) q);
835 1.1 mrg }
836 1.1.1.3 mrg }
837 1.1.1.3 mrg
838 1.1.1.3 mrg unsigned opt_argc = optimize_args->length ();
839 1.1.1.3 mrg const char **opt_argv
840 1.1.1.3 mrg = (const char **) alloca (sizeof (char *) * (opt_argc + 1));
841 1.1.1.3 mrg
842 1.1.1.3 mrg for (unsigned i = 1; i < opt_argc; i++)
843 1.1.1.3 mrg opt_argv[i] = (*optimize_args)[i];
844 1.1.1.3 mrg
845 1.1.1.3 mrg /* Now parse the options. */
846 1.1.1.3 mrg struct cl_decoded_option *decoded_options;
847 1.1.1.3 mrg unsigned int decoded_options_count;
848 1.1.1.3 mrg
849 1.1.1.3 mrg decode_cmdline_options_to_array_default_mask (opt_argc, opt_argv,
850 1.1.1.3 mrg &decoded_options,
851 1.1.1.3 mrg &decoded_options_count);
852 1.1.1.3 mrg /* Drop non-Optimization options. */
853 1.1.1.3 mrg unsigned j = 1;
854 1.1.1.3 mrg for (unsigned i = 1; i < decoded_options_count; ++i)
855 1.1.1.3 mrg {
856 1.1.1.3 mrg unsigned opt_index = decoded_options[i].opt_index;
857 1.1.1.3 mrg if (opt_index >= cl_options_count
858 1.1.1.3 mrg || ! (cl_options[opt_index].flags & CL_OPTIMIZATION))
859 1.1 mrg {
860 1.1.1.3 mrg ret = false;
861 1.1.1.3 mrg warning (OPT_Wattributes,
862 1.1.1.3 mrg "bad option %qs to attribute %<optimize%>",
863 1.1.1.3 mrg decoded_options[i].orig_option_with_args_text);
864 1.1.1.3 mrg continue;
865 1.1 mrg }
866 1.1.1.3 mrg if (i != j)
867 1.1.1.3 mrg decoded_options[j] = decoded_options[i];
868 1.1.1.3 mrg j++;
869 1.1.1.3 mrg }
870 1.1.1.3 mrg decoded_options_count = j;
871 1.1.1.3 mrg /* And apply them. */
872 1.1.1.3 mrg decode_options (&global_options, &global_options_set,
873 1.1.1.3 mrg decoded_options, decoded_options_count,
874 1.1.1.3 mrg input_location, global_dc, NULL);
875 1.1.1.3 mrg
876 1.1.1.3 mrg targetm.override_options_after_change();
877 1.1.1.3 mrg
878 1.1.1.3 mrg optimize_args->truncate (0);
879 1.1.1.3 mrg return ret;
880 1.1.1.3 mrg }
881 1.1.1.3 mrg
882 1.1.1.3 mrg /* Handle a "optimize" attribute; arguments as in
883 1.1.1.3 mrg struct attribute_spec.handler. */
884 1.1.1.3 mrg
885 1.1.1.3 mrg static tree
886 1.1.1.3 mrg d_handle_optimize_attribute (tree *node, tree name, tree args, int,
887 1.1.1.3 mrg bool *no_add_attrs)
888 1.1.1.3 mrg {
889 1.1.1.3 mrg /* Ensure we have a function type. */
890 1.1.1.3 mrg if (TREE_CODE (*node) != FUNCTION_DECL)
891 1.1.1.3 mrg {
892 1.1.1.3 mrg warning (OPT_Wattributes, "%qE attribute ignored", name);
893 1.1.1.3 mrg *no_add_attrs = true;
894 1.1 mrg }
895 1.1 mrg else
896 1.1 mrg {
897 1.1.1.3 mrg struct cl_optimization cur_opts;
898 1.1.1.3 mrg tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node);
899 1.1.1.3 mrg
900 1.1.1.3 mrg /* Save current options. */
901 1.1.1.3 mrg cl_optimization_save (&cur_opts, &global_options, &global_options_set);
902 1.1.1.3 mrg tree prev_target_node = build_target_option_node (&global_options,
903 1.1.1.3 mrg &global_options_set);
904 1.1.1.3 mrg
905 1.1.1.3 mrg /* If we previously had some optimization options, use them as the
906 1.1.1.3 mrg default. */
907 1.1.1.3 mrg gcc_options *saved_global_options = NULL;
908 1.1.1.3 mrg if (flag_checking)
909 1.1.1.3 mrg {
910 1.1.1.3 mrg saved_global_options = XNEW (gcc_options);
911 1.1.1.3 mrg *saved_global_options = global_options;
912 1.1.1.3 mrg }
913 1.1.1.3 mrg
914 1.1.1.3 mrg if (old_opts)
915 1.1.1.3 mrg cl_optimization_restore (&global_options, &global_options_set,
916 1.1.1.3 mrg TREE_OPTIMIZATION (old_opts));
917 1.1.1.3 mrg
918 1.1.1.3 mrg /* Parse options, and update the vector. */
919 1.1.1.3 mrg parse_optimize_options (args);
920 1.1.1.3 mrg DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)
921 1.1.1.3 mrg = build_optimization_node (&global_options, &global_options_set);
922 1.1.1.3 mrg tree target_node = build_target_option_node (&global_options,
923 1.1.1.3 mrg &global_options_set);
924 1.1.1.3 mrg if (prev_target_node != target_node)
925 1.1.1.3 mrg DECL_FUNCTION_SPECIFIC_TARGET (*node) = target_node;
926 1.1.1.3 mrg
927 1.1.1.3 mrg /* Restore current options. */
928 1.1.1.3 mrg cl_optimization_restore (&global_options, &global_options_set,
929 1.1.1.3 mrg &cur_opts);
930 1.1.1.3 mrg cl_target_option_restore (&global_options, &global_options_set,
931 1.1.1.3 mrg TREE_TARGET_OPTION (prev_target_node));
932 1.1.1.3 mrg if (saved_global_options != NULL)
933 1.1.1.3 mrg {
934 1.1.1.3 mrg cl_optimization_compare (saved_global_options, &global_options);
935 1.1.1.3 mrg free (saved_global_options);
936 1.1.1.3 mrg }
937 1.1.1.3 mrg }
938 1.1.1.3 mrg
939 1.1.1.3 mrg return NULL_TREE;
940 1.1.1.3 mrg }
941 1.1.1.3 mrg
942 1.1.1.3 mrg /* Handle a "noclone" attribute; arguments as in
943 1.1.1.3 mrg struct attribute_spec.handler. */
944 1.1.1.3 mrg
945 1.1.1.3 mrg static tree
946 1.1.1.3 mrg d_handle_noclone_attribute (tree *node, tree name, tree, int,
947 1.1.1.3 mrg bool *no_add_attrs)
948 1.1.1.3 mrg {
949 1.1.1.3 mrg if (TREE_CODE (*node) != FUNCTION_DECL)
950 1.1.1.3 mrg {
951 1.1.1.3 mrg warning (OPT_Wattributes, "%qE attribute ignored", name);
952 1.1 mrg *no_add_attrs = true;
953 1.1 mrg }
954 1.1 mrg
955 1.1 mrg return NULL_TREE;
956 1.1 mrg }
957 1.1 mrg
958 1.1.1.3 mrg /* Handle a "no_icf" attribute; arguments as in
959 1.1 mrg struct attribute_spec.handler. */
960 1.1 mrg
961 1.1 mrg static tree
962 1.1.1.3 mrg d_handle_noicf_attribute (tree *node, tree name, tree, int,
963 1.1.1.3 mrg bool *no_add_attrs)
964 1.1 mrg {
965 1.1.1.3 mrg if (TREE_CODE (*node) != FUNCTION_DECL)
966 1.1.1.3 mrg {
967 1.1.1.3 mrg warning (OPT_Wattributes, "%qE attribute ignored", name);
968 1.1.1.3 mrg *no_add_attrs = true;
969 1.1.1.3 mrg }
970 1.1.1.3 mrg
971 1.1.1.3 mrg return NULL_TREE;
972 1.1.1.3 mrg }
973 1.1 mrg
974 1.1.1.3 mrg /* Handle a "noipa" attribute; arguments as in
975 1.1.1.3 mrg struct attribute_spec.handler. */
976 1.1.1.3 mrg
977 1.1.1.3 mrg static tree
978 1.1.1.3 mrg d_handle_noipa_attribute (tree *node, tree name, tree, int,
979 1.1.1.3 mrg bool *no_add_attrs)
980 1.1.1.3 mrg {
981 1.1.1.3 mrg if (TREE_CODE (*node) != FUNCTION_DECL)
982 1.1 mrg {
983 1.1 mrg warning (OPT_Wattributes, "%qE attribute ignored", name);
984 1.1 mrg *no_add_attrs = true;
985 1.1.1.3 mrg }
986 1.1.1.3 mrg
987 1.1.1.3 mrg return NULL_TREE;
988 1.1.1.3 mrg }
989 1.1.1.3 mrg
990 1.1.1.3 mrg /* Handle a "section" attribute; arguments as in
991 1.1.1.3 mrg struct attribute_spec.handler. */
992 1.1.1.3 mrg
993 1.1.1.3 mrg static tree
994 1.1.1.3 mrg d_handle_section_attribute (tree *node, tree name, tree args, int flags,
995 1.1.1.3 mrg bool *no_add_attrs)
996 1.1.1.3 mrg {
997 1.1.1.3 mrg if (!targetm_common.have_named_sections)
998 1.1.1.3 mrg {
999 1.1.1.3 mrg error ("section attributes are not supported for this target");
1000 1.1.1.3 mrg *no_add_attrs = true;
1001 1.1 mrg return NULL_TREE;
1002 1.1 mrg }
1003 1.1.1.3 mrg
1004 1.1.1.3 mrg if (!VAR_OR_FUNCTION_DECL_P (*node))
1005 1.1 mrg {
1006 1.1.1.3 mrg error ("section attribute not allowed for %q+D", *node);
1007 1.1 mrg *no_add_attrs = true;
1008 1.1 mrg return NULL_TREE;
1009 1.1 mrg }
1010 1.1.1.3 mrg
1011 1.1.1.3 mrg if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
1012 1.1 mrg {
1013 1.1.1.3 mrg error ("section attribute argument not a string constant");
1014 1.1 mrg *no_add_attrs = true;
1015 1.1 mrg return NULL_TREE;
1016 1.1 mrg }
1017 1.1.1.3 mrg
1018 1.1.1.3 mrg if (VAR_P (*node)
1019 1.1.1.3 mrg && current_function_decl != NULL_TREE
1020 1.1.1.3 mrg && !TREE_STATIC (*node))
1021 1.1 mrg {
1022 1.1.1.3 mrg error ("section attribute cannot be specified for local variables");
1023 1.1.1.3 mrg *no_add_attrs = true;
1024 1.1.1.3 mrg return NULL_TREE;
1025 1.1.1.3 mrg }
1026 1.1 mrg
1027 1.1.1.3 mrg /* The decl may have already been given a section attribute
1028 1.1.1.3 mrg from a previous declaration. Ensure they match. */
1029 1.1.1.3 mrg if (DECL_SECTION_NAME (*node) != NULL
1030 1.1.1.3 mrg && strcmp (DECL_SECTION_NAME (*node),
1031 1.1.1.3 mrg TREE_STRING_POINTER (TREE_VALUE (args))) != 0)
1032 1.1.1.3 mrg {
1033 1.1.1.3 mrg error ("section of %q+D conflicts with previous declaration", *node);
1034 1.1.1.3 mrg *no_add_attrs = true;
1035 1.1.1.3 mrg return NULL_TREE;
1036 1.1.1.3 mrg }
1037 1.1.1.3 mrg
1038 1.1.1.3 mrg if (VAR_P (*node)
1039 1.1.1.3 mrg && !targetm.have_tls && targetm.emutls.tmpl_section
1040 1.1.1.3 mrg && DECL_THREAD_LOCAL_P (*node))
1041 1.1.1.3 mrg {
1042 1.1.1.3 mrg error ("section of %q+D cannot be overridden", *node);
1043 1.1.1.3 mrg *no_add_attrs = true;
1044 1.1.1.3 mrg return NULL_TREE;
1045 1.1.1.3 mrg }
1046 1.1.1.3 mrg
1047 1.1.1.3 mrg tree res = targetm.handle_generic_attribute (node, name, args, flags,
1048 1.1.1.3 mrg no_add_attrs);
1049 1.1.1.3 mrg
1050 1.1.1.3 mrg /* If the back end confirms the attribute can be added then continue onto
1051 1.1.1.3 mrg final processing. */
1052 1.1.1.3 mrg if (*no_add_attrs)
1053 1.1.1.3 mrg return NULL_TREE;
1054 1.1.1.3 mrg
1055 1.1.1.3 mrg set_decl_section_name (*node, TREE_STRING_POINTER (TREE_VALUE (args)));
1056 1.1.1.3 mrg return res;
1057 1.1.1.3 mrg }
1058 1.1.1.3 mrg
1059 1.1.1.3 mrg /* Handle a "symver" and attribute; arguments as in
1060 1.1.1.3 mrg struct attribute_spec.handler. */
1061 1.1.1.3 mrg
1062 1.1.1.3 mrg static tree
1063 1.1.1.3 mrg d_handle_symver_attribute (tree *node, tree, tree args, int, bool *no_add_attrs)
1064 1.1.1.3 mrg {
1065 1.1.1.3 mrg if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL)
1066 1.1.1.3 mrg {
1067 1.1.1.3 mrg warning (OPT_Wattributes,
1068 1.1.1.3 mrg "%<symver%> attribute only applies to functions and variables");
1069 1.1.1.3 mrg *no_add_attrs = true;
1070 1.1.1.3 mrg return NULL_TREE;
1071 1.1.1.3 mrg }
1072 1.1.1.3 mrg
1073 1.1.1.3 mrg if (!decl_in_symtab_p (*node))
1074 1.1.1.3 mrg {
1075 1.1.1.3 mrg warning (OPT_Wattributes,
1076 1.1.1.3 mrg "%<symver%> attribute is only applicable to symbols");
1077 1.1.1.3 mrg *no_add_attrs = true;
1078 1.1.1.3 mrg return NULL_TREE;
1079 1.1.1.3 mrg }
1080 1.1.1.3 mrg
1081 1.1.1.3 mrg for (; args; args = TREE_CHAIN (args))
1082 1.1.1.3 mrg {
1083 1.1.1.3 mrg tree symver = TREE_VALUE (args);
1084 1.1.1.3 mrg if (TREE_CODE (symver) != STRING_CST)
1085 1.1 mrg {
1086 1.1.1.3 mrg error ("%<symver%> attribute argument not a string constant");
1087 1.1 mrg *no_add_attrs = true;
1088 1.1 mrg return NULL_TREE;
1089 1.1 mrg }
1090 1.1 mrg
1091 1.1.1.3 mrg const char *symver_str = TREE_STRING_POINTER (symver);
1092 1.1 mrg
1093 1.1.1.3 mrg int ats = 0;
1094 1.1.1.3 mrg for (int n = 0; (int)n < TREE_STRING_LENGTH (symver); n++)
1095 1.1.1.3 mrg if (symver_str[n] == '@')
1096 1.1.1.3 mrg ats++;
1097 1.1.1.3 mrg
1098 1.1.1.3 mrg if (ats != 1 && ats != 2)
1099 1.1.1.3 mrg {
1100 1.1.1.3 mrg error ("symver attribute argument must have format %<name@nodename%>");
1101 1.1.1.3 mrg error ("%<symver%> attribute argument %qs must contain one or two "
1102 1.1.1.3 mrg "%<@%>", symver_str);
1103 1.1.1.3 mrg *no_add_attrs = true;
1104 1.1.1.3 mrg return NULL_TREE;
1105 1.1.1.3 mrg }
1106 1.1 mrg }
1107 1.1.1.3 mrg
1108 1.1.1.3 mrg return NULL_TREE;
1109 1.1 mrg }
1110 1.1 mrg
1111 1.1 mrg /* Handle a "weak" attribute; arguments as in
1112 1.1 mrg struct attribute_spec.handler. */
1113 1.1 mrg
1114 1.1 mrg static tree
1115 1.1.1.3 mrg d_handle_weak_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
1116 1.1 mrg {
1117 1.1 mrg if (TREE_CODE (*node) == FUNCTION_DECL
1118 1.1 mrg && DECL_DECLARED_INLINE_P (*node))
1119 1.1 mrg {
1120 1.1 mrg warning (OPT_Wattributes, "inline function %q+D declared weak", *node);
1121 1.1 mrg *no_add_attrs = true;
1122 1.1 mrg }
1123 1.1 mrg else if (VAR_OR_FUNCTION_DECL_P (*node))
1124 1.1 mrg {
1125 1.1 mrg struct symtab_node *n = symtab_node::get (*node);
1126 1.1 mrg if (n && n->refuse_visibility_changes)
1127 1.1 mrg error ("%q+D declared weak after being used", *node);
1128 1.1 mrg declare_weak (*node);
1129 1.1 mrg }
1130 1.1 mrg else
1131 1.1 mrg warning (OPT_Wattributes, "%qE attribute ignored", name);
1132 1.1 mrg
1133 1.1 mrg return NULL_TREE;
1134 1.1 mrg }
1135 1.1 mrg
1136 1.1.1.3 mrg /* Handle a "noplt" attribute; arguments as in
1137 1.1.1.3 mrg struct attribute_spec.handler. */
1138 1.1.1.3 mrg
1139 1.1.1.3 mrg static tree
1140 1.1.1.3 mrg d_handle_noplt_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
1141 1.1.1.3 mrg {
1142 1.1.1.3 mrg if (TREE_CODE (*node) != FUNCTION_DECL)
1143 1.1.1.3 mrg {
1144 1.1.1.3 mrg warning (OPT_Wattributes, "%qE attribute ignored", name);
1145 1.1.1.3 mrg *no_add_attrs = true;
1146 1.1.1.3 mrg }
1147 1.1.1.3 mrg
1148 1.1.1.3 mrg return NULL_TREE;
1149 1.1.1.3 mrg }
1150 1.1.1.3 mrg
1151 1.1.1.3 mrg /* Verify that argument value POS at position ARGNO to attribute ATNAME applied
1152 1.1.1.3 mrg to function FNTYPE refers to a function parameter at position POS and is a
1153 1.1.1.3 mrg valid integer type. When ZERO_BASED is true, POS is adjusted to be 1-based.
1154 1.1.1.3 mrg If successful, POS is returned. Otherwise, issue appropriate warnings and
1155 1.1.1.3 mrg return null. A non-zero 1-based ARGNO should be passed in by callers only
1156 1.1.1.3 mrg for attributes with more than one argument. */
1157 1.1.1.3 mrg
1158 1.1.1.3 mrg static tree
1159 1.1.1.3 mrg positional_argument (const_tree fntype, const_tree atname, tree pos,
1160 1.1.1.3 mrg int argno, bool zero_based)
1161 1.1.1.3 mrg {
1162 1.1.1.3 mrg tree postype = TREE_TYPE (pos);
1163 1.1.1.3 mrg
1164 1.1.1.3 mrg if (pos == error_mark_node || !postype)
1165 1.1.1.3 mrg {
1166 1.1.1.3 mrg /* Only mention the positional argument number when it's non-zero. */
1167 1.1.1.3 mrg if (argno < 1)
1168 1.1.1.3 mrg warning (OPT_Wattributes,
1169 1.1.1.3 mrg "%qE attribute argument is invalid", atname);
1170 1.1.1.3 mrg else
1171 1.1.1.3 mrg warning (OPT_Wattributes,
1172 1.1.1.3 mrg "%qE attribute argument %i is invalid", atname, argno);
1173 1.1.1.3 mrg
1174 1.1.1.3 mrg return NULL_TREE;
1175 1.1.1.3 mrg }
1176 1.1.1.3 mrg
1177 1.1.1.3 mrg if (!INTEGRAL_TYPE_P (postype))
1178 1.1.1.3 mrg {
1179 1.1.1.3 mrg /* Handle this case specially to avoid mentioning the value
1180 1.1.1.3 mrg of pointer constants in diagnostics. Only mention
1181 1.1.1.3 mrg the positional argument number when it's non-zero. */
1182 1.1.1.3 mrg if (argno < 1)
1183 1.1.1.3 mrg warning (OPT_Wattributes,
1184 1.1.1.3 mrg "%qE attribute argument has type %qT",
1185 1.1.1.3 mrg atname, postype);
1186 1.1.1.3 mrg else
1187 1.1.1.3 mrg warning (OPT_Wattributes,
1188 1.1.1.3 mrg "%qE attribute argument %i has type %qT",
1189 1.1.1.3 mrg atname, argno, postype);
1190 1.1.1.3 mrg
1191 1.1.1.3 mrg return NULL_TREE;
1192 1.1.1.3 mrg }
1193 1.1.1.3 mrg
1194 1.1.1.3 mrg if (TREE_CODE (pos) != INTEGER_CST)
1195 1.1.1.3 mrg {
1196 1.1.1.3 mrg /* Only mention the argument number when it's non-zero. */
1197 1.1.1.3 mrg if (argno < 1)
1198 1.1.1.3 mrg warning (OPT_Wattributes,
1199 1.1.1.3 mrg "%qE attribute argument value %qE is not an integer "
1200 1.1.1.3 mrg "constant",
1201 1.1.1.3 mrg atname, pos);
1202 1.1.1.3 mrg else
1203 1.1.1.3 mrg warning (OPT_Wattributes,
1204 1.1.1.3 mrg "%qE attribute argument %i value %qE is not an integer "
1205 1.1.1.3 mrg "constant",
1206 1.1.1.3 mrg atname, argno, pos);
1207 1.1.1.3 mrg
1208 1.1.1.3 mrg return NULL_TREE;
1209 1.1.1.3 mrg }
1210 1.1.1.3 mrg
1211 1.1.1.3 mrg /* Validate the value of the position argument. If 0-based, then it should
1212 1.1.1.3 mrg not be negative. If 1-based, it should be greater than zero. */
1213 1.1.1.3 mrg if ((zero_based && tree_int_cst_sgn (pos) < 0)
1214 1.1.1.3 mrg || (!zero_based && tree_int_cst_sgn (pos) < 1))
1215 1.1.1.3 mrg {
1216 1.1.1.3 mrg if (argno < 1)
1217 1.1.1.3 mrg warning (OPT_Wattributes,
1218 1.1.1.3 mrg "%qE attribute argument value %qE does not refer to "
1219 1.1.1.3 mrg "a function parameter",
1220 1.1.1.3 mrg atname, pos);
1221 1.1.1.3 mrg else
1222 1.1.1.3 mrg warning (OPT_Wattributes,
1223 1.1.1.3 mrg "%qE attribute argument %i value %qE does not refer to "
1224 1.1.1.3 mrg "a function parameter",
1225 1.1.1.3 mrg atname, argno, pos);
1226 1.1.1.3 mrg
1227 1.1.1.3 mrg return NULL_TREE;
1228 1.1.1.3 mrg }
1229 1.1.1.3 mrg
1230 1.1.1.3 mrg /* Adjust the value of pos to be 1-based. */
1231 1.1.1.3 mrg tree adjusted_pos = (zero_based)
1232 1.1.1.3 mrg ? int_const_binop (PLUS_EXPR, pos, integer_one_node) : pos;
1233 1.1.1.3 mrg
1234 1.1.1.3 mrg if (!prototype_p (fntype))
1235 1.1.1.3 mrg return adjusted_pos;
1236 1.1.1.3 mrg
1237 1.1.1.3 mrg /* Verify that the argument position does not exceed the number
1238 1.1.1.3 mrg of formal arguments to the function. */
1239 1.1.1.3 mrg unsigned nargs = type_num_arguments (fntype);
1240 1.1.1.3 mrg if (!nargs
1241 1.1.1.3 mrg || !tree_fits_uhwi_p (adjusted_pos)
1242 1.1.1.3 mrg || !IN_RANGE (tree_to_uhwi (adjusted_pos), 1, nargs))
1243 1.1.1.3 mrg {
1244 1.1.1.3 mrg if (argno < 1)
1245 1.1.1.3 mrg warning (OPT_Wattributes,
1246 1.1.1.3 mrg "%qE attribute argument value %qE exceeds the number "
1247 1.1.1.3 mrg "of function parameters %u",
1248 1.1.1.3 mrg atname, pos, nargs);
1249 1.1.1.3 mrg else
1250 1.1.1.3 mrg warning (OPT_Wattributes,
1251 1.1.1.3 mrg "%qE attribute argument %i value %qE exceeds the number "
1252 1.1.1.3 mrg "of function parameters %u",
1253 1.1.1.3 mrg atname, argno, pos, nargs);
1254 1.1.1.3 mrg
1255 1.1.1.3 mrg return NULL_TREE;
1256 1.1.1.3 mrg }
1257 1.1.1.3 mrg
1258 1.1.1.3 mrg /* Verify that the type of the referenced formal argument matches
1259 1.1.1.3 mrg the expected type. */
1260 1.1.1.3 mrg unsigned HOST_WIDE_INT ipos = tree_to_uhwi (adjusted_pos);
1261 1.1.1.3 mrg
1262 1.1.1.3 mrg /* Zero was handled above. */
1263 1.1.1.3 mrg gcc_assert (ipos != 0);
1264 1.1.1.3 mrg
1265 1.1.1.3 mrg if (tree argtype = type_argument_type (fntype, ipos))
1266 1.1.1.3 mrg {
1267 1.1.1.3 mrg /* Accept types that match INTEGRAL_TYPE_P except for bool. */
1268 1.1.1.3 mrg if (!INTEGRAL_TYPE_P (argtype) || TREE_CODE (argtype) == BOOLEAN_TYPE)
1269 1.1.1.3 mrg {
1270 1.1.1.3 mrg if (argno < 1)
1271 1.1.1.3 mrg warning (OPT_Wattributes,
1272 1.1.1.3 mrg "%qE attribute argument value %qE refers to "
1273 1.1.1.3 mrg "parameter type %qT",
1274 1.1.1.3 mrg atname, pos, argtype);
1275 1.1.1.3 mrg else
1276 1.1.1.3 mrg warning (OPT_Wattributes,
1277 1.1.1.3 mrg "%qE attribute argument %i value %qE refers to "
1278 1.1.1.3 mrg "parameter type %qT",
1279 1.1.1.3 mrg atname, argno, pos, argtype);
1280 1.1.1.3 mrg
1281 1.1.1.3 mrg return NULL_TREE;
1282 1.1.1.3 mrg }
1283 1.1.1.3 mrg
1284 1.1.1.3 mrg return adjusted_pos;
1285 1.1.1.3 mrg }
1286 1.1.1.3 mrg
1287 1.1.1.3 mrg /* Argument position exceeding number of parameters was handled above. */
1288 1.1.1.3 mrg gcc_unreachable ();
1289 1.1.1.3 mrg }
1290 1.1.1.3 mrg
1291 1.1.1.3 mrg /* Handle a "alloc_size" attribute; arguments as in
1292 1.1.1.3 mrg struct attribute_spec.handler. */
1293 1.1.1.3 mrg
1294 1.1.1.3 mrg static tree
1295 1.1.1.3 mrg d_handle_alloc_size_attribute (tree *node, tree name, tree args, int,
1296 1.1.1.3 mrg bool *no_add_attrs)
1297 1.1.1.3 mrg {
1298 1.1.1.3 mrg tree fntype = *node;
1299 1.1.1.3 mrg tree rettype = TREE_TYPE (fntype);
1300 1.1.1.3 mrg if (!POINTER_TYPE_P (rettype))
1301 1.1.1.3 mrg {
1302 1.1.1.3 mrg warning (OPT_Wattributes,
1303 1.1.1.3 mrg "%qE attribute ignored on a function returning %qT",
1304 1.1.1.3 mrg name, rettype);
1305 1.1.1.3 mrg *no_add_attrs = true;
1306 1.1.1.3 mrg return NULL_TREE;
1307 1.1.1.3 mrg }
1308 1.1.1.3 mrg
1309 1.1.1.3 mrg /* The first argument SIZE_ARG is never null. */
1310 1.1.1.3 mrg tree size_arg = TREE_VALUE (args);
1311 1.1.1.3 mrg tree next = TREE_CHAIN (args);
1312 1.1.1.3 mrg
1313 1.1.1.3 mrg /* NUM_ARG is null when the attribute includes just one argument, or is
1314 1.1.1.3 mrg explictly set to null if it has been left uninitialized by the caller. */
1315 1.1.1.3 mrg tree num_arg = NULL_TREE;
1316 1.1.1.3 mrg if (next != NULL_TREE)
1317 1.1.1.3 mrg {
1318 1.1.1.3 mrg if (TREE_VALUE (next) != TYPE_MIN_VALUE (d_int_type))
1319 1.1.1.3 mrg num_arg = TREE_VALUE (next);
1320 1.1.1.3 mrg
1321 1.1.1.3 mrg next = TREE_CHAIN (next);
1322 1.1.1.3 mrg }
1323 1.1.1.3 mrg
1324 1.1.1.3 mrg /* If ZERO_ARG is set and true, arguments positions are treated as 0-based.
1325 1.1.1.3 mrg Otherwise the default is 1-based. */
1326 1.1.1.3 mrg bool zero_based = false;
1327 1.1.1.3 mrg if (next != NULL_TREE)
1328 1.1.1.3 mrg zero_based = integer_truep (TREE_VALUE (next));
1329 1.1.1.3 mrg
1330 1.1.1.3 mrg /* Update the argument values with the real argument position. */
1331 1.1.1.3 mrg if (tree val = positional_argument (fntype, name, size_arg, num_arg ? 1 : 0,
1332 1.1.1.3 mrg zero_based))
1333 1.1.1.3 mrg TREE_VALUE (args) = val;
1334 1.1.1.3 mrg else
1335 1.1.1.3 mrg *no_add_attrs = true;
1336 1.1.1.3 mrg
1337 1.1.1.3 mrg if (num_arg != NULL_TREE)
1338 1.1.1.3 mrg {
1339 1.1.1.3 mrg args = TREE_CHAIN (args);
1340 1.1.1.3 mrg if (tree val = positional_argument (fntype, name, num_arg, 2, zero_based))
1341 1.1.1.3 mrg TREE_VALUE (args) = val;
1342 1.1.1.3 mrg else
1343 1.1.1.3 mrg *no_add_attrs = true;
1344 1.1.1.3 mrg }
1345 1.1.1.3 mrg
1346 1.1.1.3 mrg /* Terminate the original TREE_CHAIN in `args' to remove any remaining
1347 1.1.1.3 mrg D-specific `alloc_size` arguments. */
1348 1.1.1.3 mrg TREE_CHAIN (args) = NULL_TREE;
1349 1.1.1.3 mrg
1350 1.1.1.3 mrg return NULL_TREE;
1351 1.1.1.3 mrg }
1352 1.1.1.3 mrg
1353 1.1.1.3 mrg /* Handle a "cold" and attribute; arguments as in
1354 1.1.1.3 mrg struct attribute_spec.handler. */
1355 1.1.1.3 mrg
1356 1.1.1.3 mrg static tree
1357 1.1.1.3 mrg d_handle_cold_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
1358 1.1.1.3 mrg {
1359 1.1.1.3 mrg if (TREE_CODE (*node) != FUNCTION_DECL)
1360 1.1.1.3 mrg {
1361 1.1.1.3 mrg warning (OPT_Wattributes, "%qE attribute ignored", name);
1362 1.1.1.3 mrg *no_add_attrs = true;
1363 1.1.1.3 mrg }
1364 1.1.1.3 mrg
1365 1.1.1.3 mrg return NULL_TREE;
1366 1.1.1.3 mrg }
1367 1.1.1.3 mrg
1368 1.1.1.3 mrg /* Handle a "restrict" attribute; arguments as in
1369 1.1.1.3 mrg struct attribute_spec.handler. */
1370 1.1.1.3 mrg
1371 1.1.1.3 mrg static tree
1372 1.1.1.3 mrg d_handle_restrict_attribute (tree *node, tree name, tree, int,
1373 1.1.1.3 mrg bool *no_add_attrs)
1374 1.1.1.3 mrg {
1375 1.1.1.3 mrg if (TREE_CODE (*node) == PARM_DECL && POINTER_TYPE_P (TREE_TYPE (*node)))
1376 1.1.1.3 mrg {
1377 1.1.1.3 mrg TREE_TYPE (*node) = build_qualified_type (TREE_TYPE (*node),
1378 1.1.1.3 mrg TYPE_QUAL_RESTRICT);
1379 1.1.1.3 mrg }
1380 1.1.1.3 mrg else
1381 1.1.1.3 mrg {
1382 1.1.1.3 mrg warning (OPT_Wattributes, "%qE attribute ignored", name);
1383 1.1.1.3 mrg *no_add_attrs = true;
1384 1.1.1.3 mrg }
1385 1.1.1.3 mrg
1386 1.1.1.3 mrg return NULL_TREE;
1387 1.1.1.3 mrg }
1388 1.1.1.3 mrg
1389 1.1.1.3 mrg /* Handle a "used" attribute; arguments as in
1390 1.1.1.3 mrg struct attribute_spec.handler. */
1391 1.1.1.3 mrg
1392 1.1.1.3 mrg static tree
1393 1.1.1.3 mrg d_handle_used_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
1394 1.1.1.3 mrg {
1395 1.1.1.3 mrg if (TREE_CODE (*node) == FUNCTION_DECL
1396 1.1.1.3 mrg || (VAR_P (*node) && TREE_STATIC (*node))
1397 1.1.1.3 mrg || (TREE_CODE (*node) == TYPE_DECL))
1398 1.1.1.3 mrg {
1399 1.1.1.3 mrg TREE_USED (*node) = 1;
1400 1.1.1.3 mrg DECL_PRESERVE_P (*node) = 1;
1401 1.1.1.3 mrg if (VAR_P (*node))
1402 1.1.1.3 mrg DECL_READ_P (*node) = 1;
1403 1.1.1.3 mrg }
1404 1.1.1.3 mrg else
1405 1.1.1.3 mrg {
1406 1.1.1.3 mrg warning (OPT_Wattributes, "%qE attribute ignored", name);
1407 1.1.1.3 mrg *no_add_attrs = true;
1408 1.1.1.3 mrg }
1409 1.1.1.3 mrg
1410 1.1.1.3 mrg return NULL_TREE;
1411 1.1.1.3 mrg }
1412