ada: Fix wrong resolution for hidden discriminant in predicate
[official-gcc.git] / gcc / d / d-attribs.cc
blobcc46220ddc2f7f9c99466624d9c59de22bb90bea
1 /* d-attribs.c -- D attributes handling.
2 Copyright (C) 2015-2023 Free Software Foundation, Inc.
4 GCC is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
9 GCC is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with GCC; see the file COPYING3. If not see
16 <http://www.gnu.org/licenses/>. */
18 /* Implementation of attribute handlers for user defined attributes and
19 internal built-in functions. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
25 #include "dmd/attrib.h"
26 #include "dmd/declaration.h"
27 #include "dmd/expression.h"
28 #include "dmd/module.h"
29 #include "dmd/mtype.h"
30 #include "dmd/template.h"
32 #include "tree.h"
33 #include "diagnostic.h"
34 #include "tm.h"
35 #include "cgraph.h"
36 #include "toplev.h"
37 #include "target.h"
38 #include "common/common-target.h"
39 #include "stringpool.h"
40 #include "attribs.h"
41 #include "varasm.h"
42 #include "fold-const.h"
43 #include "opts.h"
45 #include "d-tree.h"
48 /* Internal attribute handlers for built-in functions. */
49 static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
50 static tree handle_leaf_attribute (tree *, tree, tree, int, bool *);
51 static tree handle_const_attribute (tree *, tree, tree, int, bool *);
52 static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
53 static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
54 static tree handle_novops_attribute (tree *, tree, tree, int, bool *);
55 static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
56 static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
57 static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
58 static tree handle_transaction_pure_attribute (tree *, tree, tree, int, bool *);
59 static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
60 static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *);
61 static tree handle_omp_declare_simd_attribute (tree *, tree, tree, int, bool *);
63 /* D attribute handlers for user defined attributes. */
64 static tree d_handle_noinline_attribute (tree *, tree, tree, int, bool *);
65 static tree d_handle_always_inline_attribute (tree *, tree, tree, int, bool *);
66 static tree d_handle_flatten_attribute (tree *, tree, tree, int, bool *);
67 static tree d_handle_target_attribute (tree *, tree, tree, int, bool *);
68 static tree d_handle_target_clones_attribute (tree *, tree, tree, int, bool *);
69 static tree d_handle_optimize_attribute (tree *, tree, tree, int, bool *);
70 static tree d_handle_noclone_attribute (tree *, tree, tree, int, bool *);
71 static tree d_handle_noicf_attribute (tree *, tree, tree, int, bool *);
72 static tree d_handle_noipa_attribute (tree *, tree, tree, int, bool *);
73 static tree d_handle_section_attribute (tree *, tree, tree, int, bool *);
74 static tree d_handle_symver_attribute (tree *, tree, tree, int, bool *);
75 static tree d_handle_weak_attribute (tree *, tree, tree, int, bool *) ;
76 static tree d_handle_noplt_attribute (tree *, tree, tree, int, bool *) ;
77 static tree d_handle_alloc_size_attribute (tree *, tree, tree, int, bool *);
78 static tree d_handle_cold_attribute (tree *, tree, tree, int, bool *);
79 static tree d_handle_register_attribute (tree *, tree, tree, int, bool *);
80 static tree d_handle_restrict_attribute (tree *, tree, tree, int, bool *);
81 static tree d_handle_used_attribute (tree *, tree, tree, int, bool *);
82 static tree d_handle_visibility_attribute (tree *, tree, tree, int, bool *);
83 static tree d_handle_no_sanitize_attribute (tree *, tree, tree, int, bool *);
84 static tree d_handle_simd_attribute (tree *, tree, tree, int, bool *);
86 /* Helper to define attribute exclusions. */
87 #define ATTR_EXCL(name, function, type, variable) \
88 { name, function, type, variable }
90 /* Define attributes that are mutually exclusive with one another. */
91 static const struct attribute_spec::exclusions attr_noreturn_exclusions[] =
93 ATTR_EXCL ("alloc_size", true, true, true),
94 ATTR_EXCL ("const", true, true, true),
95 ATTR_EXCL ("malloc", true, true, true),
96 ATTR_EXCL ("pure", true, true, true),
97 ATTR_EXCL ("returns_twice", true, true, true),
98 ATTR_EXCL (NULL, false, false, false),
101 static const struct attribute_spec::exclusions attr_returns_twice_exclusions[] =
103 ATTR_EXCL ("noreturn", true, true, true),
104 ATTR_EXCL (NULL, false, false, false),
107 static const struct attribute_spec::exclusions attr_const_pure_exclusions[] =
109 ATTR_EXCL ("alloc_size", true, true, true),
110 ATTR_EXCL ("const", true, true, true),
111 ATTR_EXCL ("noreturn", true, true, true),
112 ATTR_EXCL ("pure", true, true, true),
113 ATTR_EXCL (NULL, false, false, false)
116 static const struct attribute_spec::exclusions attr_inline_exclusions[] =
118 ATTR_EXCL ("noinline", true, true, true),
119 ATTR_EXCL ("target_clones", true, true, true),
120 ATTR_EXCL (NULL, false, false, false),
123 static const struct attribute_spec::exclusions attr_noinline_exclusions[] =
125 ATTR_EXCL ("always_inline", true, true, true),
126 ATTR_EXCL (NULL, false, false, false),
129 static const struct attribute_spec::exclusions attr_target_exclusions[] =
131 ATTR_EXCL ("target_clones", true, true, true),
132 ATTR_EXCL (NULL, false, false, false),
135 static const struct attribute_spec::exclusions attr_target_clones_exclusions[] =
137 ATTR_EXCL ("always_inline", true, true, true),
138 ATTR_EXCL ("target", true, true, true),
139 ATTR_EXCL (NULL, false, false, false),
142 static const struct attribute_spec::exclusions attr_alloc_exclusions[] =
144 ATTR_EXCL ("const", true, true, true),
145 ATTR_EXCL ("noreturn", true, true, true),
146 ATTR_EXCL ("pure", true, true, true),
147 ATTR_EXCL (NULL, false, false, false),
150 extern const struct attribute_spec::exclusions attr_cold_hot_exclusions[] =
152 ATTR_EXCL ("cold", true, true, true),
153 ATTR_EXCL ("hot", true, true, true),
154 ATTR_EXCL (NULL, false, false, false)
157 /* Helper to define an attribute. */
158 #define ATTR_SPEC(name, min_len, max_len, decl_req, type_req, fn_type_req, \
159 affects_type_identity, handler, exclude) \
160 { name, min_len, max_len, decl_req, type_req, fn_type_req, \
161 affects_type_identity, handler, exclude }
163 /* Table of machine-independent attributes.
164 For internal use (marking of built-ins) only. */
165 const attribute_spec d_langhook_common_attribute_table[] =
167 ATTR_SPEC ("noreturn", 0, 0, true, false, false, false,
168 handle_noreturn_attribute, attr_noreturn_exclusions),
169 ATTR_SPEC ("leaf", 0, 0, true, false, false, false,
170 handle_leaf_attribute, NULL),
171 ATTR_SPEC ("const", 0, 0, true, false, false, false,
172 handle_const_attribute, attr_const_pure_exclusions),
173 ATTR_SPEC ("malloc", 0, 0, true, false, false, false,
174 handle_malloc_attribute, NULL),
175 ATTR_SPEC ("returns_twice", 0, 0, true, false, false, false,
176 handle_returns_twice_attribute, attr_returns_twice_exclusions),
177 ATTR_SPEC ("pure", 0, 0, true, false, false, false,
178 handle_pure_attribute, attr_const_pure_exclusions),
179 ATTR_SPEC ("nonnull", 0, -1, false, true, true, false,
180 handle_nonnull_attribute, NULL),
181 ATTR_SPEC ("nothrow", 0, 0, true, false, false, false,
182 handle_nothrow_attribute, NULL),
183 ATTR_SPEC ("transaction_pure", 0, 0, false, true, true, false,
184 handle_transaction_pure_attribute, NULL),
185 ATTR_SPEC ("no vops", 0, 0, true, false, false, false,
186 handle_novops_attribute, NULL),
187 ATTR_SPEC ("type generic", 0, 0, false, true, true, false,
188 handle_type_generic_attribute, NULL),
189 ATTR_SPEC ("fn spec", 1, 1, false, true, true, false,
190 handle_fnspec_attribute, NULL),
191 ATTR_SPEC ("omp declare simd", 0, -1, true, false, false, false,
192 handle_omp_declare_simd_attribute, NULL),
193 ATTR_SPEC (NULL, 0, 0, false, false, false, false, NULL, NULL),
196 /* Table of D language attributes exposed by `gcc.attribute' UDAs. */
197 const attribute_spec d_langhook_attribute_table[] =
199 ATTR_SPEC ("noinline", 0, 0, true, false, false, false,
200 d_handle_noinline_attribute, attr_noinline_exclusions),
201 ATTR_SPEC ("always_inline", 0, 0, true, false, false, false,
202 d_handle_always_inline_attribute, attr_inline_exclusions),
203 ATTR_SPEC ("flatten", 0, 0, true, false, false, false,
204 d_handle_flatten_attribute, NULL),
205 ATTR_SPEC ("target", 1, -1, true, false, false, false,
206 d_handle_target_attribute, attr_target_exclusions),
207 ATTR_SPEC ("target_clones", 1, -1, true, false, false, false,
208 d_handle_target_clones_attribute, attr_target_clones_exclusions),
209 ATTR_SPEC ("optimize", 1, -1, true, false, false, false,
210 d_handle_optimize_attribute, NULL),
211 ATTR_SPEC ("noclone", 0, 0, true, false, false, false,
212 d_handle_noclone_attribute, NULL),
213 ATTR_SPEC ("no_icf", 0, 0, true, false, false, false,
214 d_handle_noicf_attribute, NULL),
215 ATTR_SPEC ("noipa", 0, 0, true, false, false, false,
216 d_handle_noipa_attribute, NULL),
217 ATTR_SPEC ("section", 1, 1, true, false, false, false,
218 d_handle_section_attribute, NULL),
219 ATTR_SPEC ("symver", 1, -1, true, false, false, false,
220 d_handle_symver_attribute, NULL),
221 ATTR_SPEC ("weak", 0, 0, true, false, false, false,
222 d_handle_weak_attribute, NULL),
223 ATTR_SPEC ("noplt", 0, 0, true, false, false, false,
224 d_handle_noplt_attribute, NULL),
225 ATTR_SPEC ("alloc_size", 1, 3, false, true, true, false,
226 d_handle_alloc_size_attribute, attr_alloc_exclusions),
227 ATTR_SPEC ("cold", 0, 0, true, false, false, false,
228 d_handle_cold_attribute, attr_cold_hot_exclusions),
229 ATTR_SPEC ("no_sanitize", 1, -1, true, false, false, false,
230 d_handle_no_sanitize_attribute, NULL),
231 ATTR_SPEC ("register", 1, 1, true, false, false, false,
232 d_handle_register_attribute, NULL),
233 ATTR_SPEC ("restrict", 0, 0, true, false, false, false,
234 d_handle_restrict_attribute, NULL),
235 ATTR_SPEC ("simd", 0, 1, true, false, false, false,
236 d_handle_simd_attribute, NULL),
237 ATTR_SPEC ("used", 0, 0, true, false, false, false,
238 d_handle_used_attribute, NULL),
239 ATTR_SPEC ("visibility", 1, 1, false, false, false, false,
240 d_handle_visibility_attribute, NULL),
241 ATTR_SPEC (NULL, 0, 0, false, false, false, false, NULL, NULL),
245 /* Insert the type attribute ATTRNAME with value VALUE into TYPE.
246 Returns a new variant of the original type declaration. */
248 tree
249 insert_type_attribute (tree type, const char *attrname, tree value)
251 tree ident = get_identifier (attrname);
253 if (value)
254 value = tree_cons (NULL_TREE, value, NULL_TREE);
256 decl_attributes (&type, build_tree_list (ident, value),
257 ATTR_FLAG_TYPE_IN_PLACE);
258 return type;
261 /* Insert the decl attribute ATTRNAME with value VALUE into DECL. */
263 tree
264 insert_decl_attribute (tree decl, const char *attrname, tree value)
266 tree ident = get_identifier (attrname);
268 if (value)
269 value = tree_cons (NULL_TREE, value, NULL_TREE);
271 decl_attributes (&decl, build_tree_list (ident, value), 0);
273 return decl;
276 /* Returns TRUE if NAME is an attribute recognized as being handled by
277 the `gcc.attribute' module. */
279 static bool
280 uda_attribute_p (const char *name)
282 tree ident = get_identifier (name);
284 /* Search both our language, and target attribute tables.
285 Common and format attributes are kept internal. */
286 for (const attribute_spec *p = d_langhook_attribute_table; p->name; p++)
288 if (get_identifier (p->name) == ident)
289 return true;
292 if (targetm.attribute_table)
294 for (const attribute_spec *p = targetm.attribute_table; p->name; p++)
296 if (get_identifier (p->name) == ident)
297 return true;
301 return false;
304 /* [attribute/uda]
306 User Defined Attributes (UDA) are compile time expressions that can be
307 attached to a declaration. These attributes can then be queried, extracted,
308 and manipulated at compile-time. There is no run-time component to them.
310 Expand and merge all UDAs found in the EATTRS list that are of type
311 `gcc.attribute.Attribute'. This symbol is internally recognized by the
312 compiler and maps them to their equivalent GCC attribute. */
314 static tree
315 build_attributes (Expressions *eattrs)
317 if (!eattrs)
318 return NULL_TREE;
320 expandTuples (eattrs);
322 tree attribs = NULL_TREE;
324 for (size_t i = 0; i < eattrs->length; i++)
326 Expression *attr = (*eattrs)[i];
327 Dsymbol *sym = attr->type->toDsymbol (0);
329 if (!sym)
331 /* If attribute is a template symbol, perhaps arguments were not
332 supplied, so warn about attribute having no effect. */
333 if (TemplateExp *te = attr->isTemplateExp ())
335 if (!te->td || !te->td->onemember)
336 continue;
338 sym = te->td->onemember;
340 else
341 continue;
344 /* Attribute symbol must come from the `gcc.attribute' module. */
345 Dsymbol *mod = sym->getModule ();
346 if (!(strcmp (mod->toChars (), "attributes") == 0
347 && mod->parent != NULL
348 && strcmp (mod->parent->toChars (), "gcc") == 0
349 && !mod->parent->parent))
350 continue;
352 /* Get the result of the attribute if it hasn't already been folded. */
353 if (attr->op == EXP::call)
354 attr = attr->ctfeInterpret ();
356 if (attr->op != EXP::structLiteral)
358 warning_at (make_location_t (attr->loc), OPT_Wattributes,
359 "%qE attribute has no effect",
360 get_identifier (sym->toChars ()));
361 continue;
364 /* Should now have a struct `Attribute("attrib", "value", ...)'
365 initializer list. */
366 Expressions *elems = attr->isStructLiteralExp ()->elements;
367 Expression *e0 = (*elems)[0];
369 if (e0->op != EXP::string_)
371 warning_at (make_location_t (attr->loc), OPT_Wattributes,
372 "unknown attribute %qs", e0->toChars());
373 continue;
376 StringExp *se = e0->toStringExp ();
377 gcc_assert (se->sz == 1);
379 /* Empty string attribute, just ignore it. */
380 if (se->len == 0)
381 continue;
383 /* Check if the attribute is recognized and handled.
384 Done here to report the diagnostic at the right location. */
385 const char *name = (const char *)(se->len ? se->string : "");
386 if (!uda_attribute_p (name))
388 warning_at (make_location_t (attr->loc), OPT_Wattributes,
389 "unknown attribute %qs", name);
390 continue;
393 /* Chain all attribute arguments together. */
394 tree args = NULL_TREE;
396 for (size_t j = 1; j < elems->length; j++)
398 Expression *e = (*elems)[j];
399 /* Stop after the first `void' argument. */
400 if (e == NULL)
401 break;
403 StringExp *s = e->isStringExp ();
404 tree t;
405 if (s != NULL && s->sz == 1)
407 const char *string = (const char *)(s->len ? s->string : "");
408 t = build_string (s->len, string);
410 else
411 t = build_expr (e);
413 args = chainon (args, build_tree_list (0, t));
416 tree list = build_tree_list (get_identifier (name), args);
417 attribs = chainon (attribs, list);
420 return attribs;
423 /* If any GCC attributes are found in the declaration SYM, apply them to the
424 type or decl NODE. */
426 void
427 apply_user_attributes (Dsymbol *sym, tree node)
429 UserAttributeDeclaration *uda = sym->userAttribDecl ();
430 if (uda == NULL)
431 return;
433 location_t saved_location = input_location;
434 input_location = make_location_t (sym->loc);
436 int attr_flags = 0;
437 if (TYPE_P (node) && !COMPLETE_TYPE_P (node))
438 attr_flags |= ATTR_FLAG_TYPE_IN_PLACE;
440 Expressions *attrs = uda->getAttributes ();
441 decl_attributes (&node, build_attributes (attrs), attr_flags);
443 input_location = saved_location;
446 /* Built-in attribute handlers.
447 These functions take the arguments:
448 (tree *node, tree name, tree args, int flags, bool *no_add_attrs) */
450 /* Handle a "noreturn" attribute; arguments as in
451 struct attribute_spec.handler. */
453 static tree
454 handle_noreturn_attribute (tree *node, tree, tree, int, bool *)
456 tree type = TREE_TYPE (*node);
458 if (TREE_CODE (*node) == FUNCTION_DECL)
459 TREE_THIS_VOLATILE (*node) = 1;
460 else if (TREE_CODE (type) == POINTER_TYPE
461 && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
462 TREE_TYPE (*node)
463 = build_pointer_type
464 (build_type_variant (TREE_TYPE (type),
465 TYPE_READONLY (TREE_TYPE (type)), 1));
466 else
467 gcc_unreachable ();
469 return NULL_TREE;
472 /* Handle a "leaf" attribute; arguments as in
473 struct attribute_spec.handler. */
475 static tree
476 handle_leaf_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
478 if (TREE_CODE (*node) != FUNCTION_DECL)
480 warning (OPT_Wattributes, "%qE attribute ignored", name);
481 *no_add_attrs = true;
483 if (!TREE_PUBLIC (*node))
485 warning (OPT_Wattributes, "%qE attribute has no effect", name);
486 *no_add_attrs = true;
489 return NULL_TREE;
492 /* Handle a "const" attribute; arguments as in
493 struct attribute_spec.handler. */
495 static tree
496 handle_const_attribute (tree *node, tree, tree, int, bool *)
498 tree type = TREE_TYPE (*node);
500 if (TREE_CODE (*node) == FUNCTION_DECL)
501 TREE_READONLY (*node) = 1;
502 else if (TREE_CODE (type) == POINTER_TYPE
503 && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
504 TREE_TYPE (*node)
505 = build_pointer_type
506 (build_type_variant (TREE_TYPE (type), 1,
507 TREE_THIS_VOLATILE (TREE_TYPE (type))));
508 else
509 gcc_unreachable ();
511 return NULL_TREE;
514 /* Handle a "malloc" attribute; arguments as in
515 struct attribute_spec.handler. */
517 tree
518 handle_malloc_attribute (tree *node, tree, tree, int, bool *)
520 gcc_assert (TREE_CODE (*node) == FUNCTION_DECL
521 && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node))));
522 DECL_IS_MALLOC (*node) = 1;
523 return NULL_TREE;
526 /* Handle a "pure" attribute; arguments as in
527 struct attribute_spec.handler. */
529 static tree
530 handle_pure_attribute (tree *node, tree, tree, int, bool *)
532 gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
533 DECL_PURE_P (*node) = 1;
534 return NULL_TREE;
537 /* Handle a "no vops" attribute; arguments as in
538 struct attribute_spec.handler. */
540 static tree
541 handle_novops_attribute (tree *node, tree, tree, int, bool *)
543 gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
544 DECL_IS_NOVOPS (*node) = 1;
545 return NULL_TREE;
548 /* Helper for nonnull attribute handling; fetch the operand number
549 from the attribute argument list. */
551 static bool
552 get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp)
554 /* Verify the arg number is a constant. */
555 if (!tree_fits_uhwi_p (arg_num_expr))
556 return false;
558 *valp = TREE_INT_CST_LOW (arg_num_expr);
559 return true;
562 /* Handle the "nonnull" attribute. */
564 static tree
565 handle_nonnull_attribute (tree *node, tree, tree args, int, bool *)
567 tree type = *node;
569 /* If no arguments are specified, all pointer arguments should be
570 non-null. Verify a full prototype is given so that the arguments
571 will have the correct types when we actually check them later.
572 Avoid diagnosing type-generic built-ins since those have no
573 prototype. */
574 if (!args)
576 gcc_assert (prototype_p (type)
577 || !TYPE_ATTRIBUTES (type)
578 || lookup_attribute ("type generic", TYPE_ATTRIBUTES (type)));
580 return NULL_TREE;
583 /* Argument list specified. Verify that each argument number references
584 a pointer argument. */
585 for (; args; args = TREE_CHAIN (args))
587 tree argument;
588 unsigned HOST_WIDE_INT arg_num = 0, ck_num;
590 if (!get_nonnull_operand (TREE_VALUE (args), &arg_num))
591 gcc_unreachable ();
593 argument = TYPE_ARG_TYPES (type);
594 if (argument)
596 for (ck_num = 1; ; ck_num++)
598 if (!argument || ck_num == arg_num)
599 break;
600 argument = TREE_CHAIN (argument);
603 gcc_assert (argument
604 && TREE_CODE (TREE_VALUE (argument)) == POINTER_TYPE);
608 return NULL_TREE;
611 /* Handle a "nothrow" attribute; arguments as in
612 struct attribute_spec.handler. */
614 static tree
615 handle_nothrow_attribute (tree *node, tree, tree, int, bool *)
617 gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
618 TREE_NOTHROW (*node) = 1;
619 return NULL_TREE;
622 /* Handle a "type generic" attribute; arguments as in
623 struct attribute_spec.handler. */
625 static tree
626 handle_type_generic_attribute (tree *node, tree, tree, int, bool *)
628 /* Ensure we have a function type. */
629 gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
631 /* Ensure we have a variadic function. */
632 gcc_assert (!prototype_p (*node) || stdarg_p (*node));
634 return NULL_TREE;
637 /* Handle a "transaction_pure" attribute; arguments as in
638 struct attribute_spec.handler. */
640 static tree
641 handle_transaction_pure_attribute (tree *node, tree, tree, int, bool *)
643 /* Ensure we have a function type. */
644 gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
646 return NULL_TREE;
649 /* Handle a "returns_twice" attribute; arguments as in
650 struct attribute_spec.handler. */
652 static tree
653 handle_returns_twice_attribute (tree *node, tree, tree, int, bool *)
655 gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
657 DECL_IS_RETURNS_TWICE (*node) = 1;
659 return NULL_TREE;
662 /* Handle a "fn spec" attribute; arguments as in
663 struct attribute_spec.handler. */
665 tree
666 handle_fnspec_attribute (tree *, tree, tree args, int, bool *)
668 gcc_assert (args
669 && TREE_CODE (TREE_VALUE (args)) == STRING_CST
670 && !TREE_CHAIN (args));
671 return NULL_TREE;
674 /* Handle an "omp declare simd" attribute; arguments as in
675 struct attribute_spec.handler. */
677 tree
678 handle_omp_declare_simd_attribute (tree *node, tree, tree, int, bool *)
680 gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
681 return NULL_TREE;
684 /* Language specific attribute handlers.
685 These functions take the arguments:
686 (tree *node, tree name, tree args, int flags, bool *no_add_attrs) */
688 /* Handle a "noinline" attribute; arguments as in
689 struct attribute_spec.handler. */
691 static tree
692 d_handle_noinline_attribute (tree *node, tree name, tree, int,
693 bool *no_add_attrs)
695 if (TREE_CODE (*node) == FUNCTION_DECL)
696 DECL_UNINLINABLE (*node) = 1;
697 else
699 warning (OPT_Wattributes, "%qE attribute ignored", name);
700 *no_add_attrs = true;
703 return NULL_TREE;
706 /* Handle a "always_inline" attribute; arguments as in
707 struct attribute_spec.handler. */
709 static tree
710 d_handle_always_inline_attribute (tree *node, tree name, tree, int,
711 bool *no_add_attrs)
713 if (TREE_CODE (*node) == FUNCTION_DECL)
715 DECL_DECLARED_INLINE_P (*node) = 1;
716 DECL_DISREGARD_INLINE_LIMITS (*node) = 1;
718 else
720 warning (OPT_Wattributes, "%qE attribute ignored", name);
721 *no_add_attrs = true;
724 return NULL_TREE;
727 /* Handle a "flatten" attribute; arguments as in
728 struct attribute_spec.handler. */
730 static tree
731 d_handle_flatten_attribute (tree *node, tree name, tree, int,
732 bool *no_add_attrs)
734 if (TREE_CODE (*node) != FUNCTION_DECL)
736 warning (OPT_Wattributes, "%qE attribute ignored", name);
737 *no_add_attrs = true;
740 return NULL_TREE;
743 /* Handle a "target" attribute; arguments as in
744 struct attribute_spec.handler. */
746 static tree
747 d_handle_target_attribute (tree *node, tree name, tree args, int flags,
748 bool *no_add_attrs)
750 /* Ensure we have a function type. */
751 if (TREE_CODE (*node) != FUNCTION_DECL)
753 warning (OPT_Wattributes, "%qE attribute ignored", name);
754 *no_add_attrs = true;
756 else if (!targetm.target_option.valid_attribute_p (*node, name, args, flags))
757 *no_add_attrs = true;
759 /* Check that there's no empty string in values of the attribute. */
760 for (tree t = args; t != NULL_TREE; t = TREE_CHAIN (t))
762 tree value = TREE_VALUE (t);
763 if (TREE_CODE (value) != STRING_CST
764 || (TREE_STRING_LENGTH (value) != 0
765 && TREE_STRING_POINTER (value)[0] != '\0'))
766 continue;
768 warning (OPT_Wattributes, "empty string in attribute %<target%>");
769 *no_add_attrs = true;
772 return NULL_TREE;
775 /* Handle a "target_clones" attribute; arguments as in
776 struct attribute_spec.handler. */
778 static tree
779 d_handle_target_clones_attribute (tree *node, tree name, tree, int,
780 bool *no_add_attrs)
782 /* Ensure we have a function type. */
783 if (TREE_CODE (*node) != FUNCTION_DECL)
785 warning (OPT_Wattributes, "%qE attribute ignored", name);
786 *no_add_attrs = true;
788 else
790 /* Do not inline functions with multiple clone targets. */
791 DECL_UNINLINABLE (*node) = 1;
794 return NULL_TREE;
797 /* Arguments being collected for optimization. */
798 static GTY(()) vec <const char *, va_gc> *optimize_args;
800 /* Inner function to convert a TREE_LIST to argv string to parse the optimize
801 options in ARGS. */
803 static bool
804 parse_optimize_options (tree args)
806 bool ret = true;
808 /* Build up argv vector. Just in case the string is stored away, use garbage
809 collected strings. */
810 vec_safe_truncate (optimize_args, 0);
811 vec_safe_push (optimize_args, (const char *) NULL);
813 for (tree ap = args; ap != NULL_TREE; ap = TREE_CHAIN (ap))
815 tree value = TREE_VALUE (ap);
817 if (TREE_CODE (value) == INTEGER_CST)
819 char buffer[20];
820 sprintf (buffer, "-O%ld", (long) TREE_INT_CST_LOW (value));
821 vec_safe_push (optimize_args, ggc_strdup (buffer));
823 else if (TREE_CODE (value) == STRING_CST)
825 size_t len = TREE_STRING_LENGTH (value);
826 const char *p = TREE_STRING_POINTER (value);
828 /* If the user supplied -Oxxx or -fxxx, only allow -Oxxx or -fxxx
829 options. */
830 if (*p == '-' && p[1] != 'O' && p[1] != 'f')
832 ret = false;
833 warning (OPT_Wattributes,
834 "bad option %qs to attribute %<optimize%>", p);
835 continue;
838 /* Can't use GC memory here. */
839 char *q = XOBNEWVEC (&opts_obstack, char, len + 3);
840 char *r = q;
842 if (*p != '-')
844 *r++ = '-';
846 /* Assume that Ox is -Ox, a numeric value is -Ox, a s by
847 itself is -Os, and any other switch begins with a -f. */
848 if ((*p >= '0' && *p <= '9') || (p[0] == 's' && p[1] == '\0'))
849 *r++ = 'O';
850 else if (*p != 'O')
851 *r++ = 'f';
854 memcpy (r, p, len);
855 r[len] = '\0';
856 vec_safe_push (optimize_args, (const char *) q);
860 unsigned opt_argc = optimize_args->length ();
861 const char **opt_argv
862 = (const char **) alloca (sizeof (char *) * (opt_argc + 1));
864 for (unsigned i = 1; i < opt_argc; i++)
865 opt_argv[i] = (*optimize_args)[i];
867 /* Now parse the options. */
868 struct cl_decoded_option *decoded_options;
869 unsigned int decoded_options_count;
871 decode_cmdline_options_to_array_default_mask (opt_argc, opt_argv,
872 &decoded_options,
873 &decoded_options_count);
874 /* Drop non-Optimization options. */
875 unsigned j = 1;
876 for (unsigned i = 1; i < decoded_options_count; ++i)
878 unsigned opt_index = decoded_options[i].opt_index;
879 if (opt_index >= cl_options_count
880 || ! (cl_options[opt_index].flags & CL_OPTIMIZATION))
882 ret = false;
883 warning (OPT_Wattributes,
884 "bad option %qs to attribute %<optimize%>",
885 decoded_options[i].orig_option_with_args_text);
886 continue;
888 if (i != j)
889 decoded_options[j] = decoded_options[i];
890 j++;
892 decoded_options_count = j;
893 /* And apply them. */
894 decode_options (&global_options, &global_options_set,
895 decoded_options, decoded_options_count,
896 input_location, global_dc, NULL);
898 targetm.override_options_after_change();
900 optimize_args->truncate (0);
901 return ret;
904 /* Handle a "optimize" attribute; arguments as in
905 struct attribute_spec.handler. */
907 static tree
908 d_handle_optimize_attribute (tree *node, tree name, tree args, int,
909 bool *no_add_attrs)
911 /* Ensure we have a function type. */
912 if (TREE_CODE (*node) != FUNCTION_DECL)
914 warning (OPT_Wattributes, "%qE attribute ignored", name);
915 *no_add_attrs = true;
917 else
919 struct cl_optimization cur_opts;
920 tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node);
922 /* Save current options. */
923 cl_optimization_save (&cur_opts, &global_options, &global_options_set);
924 tree prev_target_node = build_target_option_node (&global_options,
925 &global_options_set);
927 /* If we previously had some optimization options, use them as the
928 default. */
929 gcc_options *saved_global_options = NULL;
930 if (flag_checking)
932 saved_global_options = XNEW (gcc_options);
933 *saved_global_options = global_options;
936 if (old_opts)
937 cl_optimization_restore (&global_options, &global_options_set,
938 TREE_OPTIMIZATION (old_opts));
940 /* Parse options, and update the vector. */
941 parse_optimize_options (args);
942 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)
943 = build_optimization_node (&global_options, &global_options_set);
944 tree target_node = build_target_option_node (&global_options,
945 &global_options_set);
946 if (prev_target_node != target_node)
947 DECL_FUNCTION_SPECIFIC_TARGET (*node) = target_node;
949 /* Restore current options. */
950 cl_optimization_restore (&global_options, &global_options_set,
951 &cur_opts);
952 cl_target_option_restore (&global_options, &global_options_set,
953 TREE_TARGET_OPTION (prev_target_node));
954 if (saved_global_options != NULL)
956 cl_optimization_compare (saved_global_options, &global_options);
957 free (saved_global_options);
961 return NULL_TREE;
964 /* Handle a "noclone" attribute; arguments as in
965 struct attribute_spec.handler. */
967 static tree
968 d_handle_noclone_attribute (tree *node, tree name, tree, int,
969 bool *no_add_attrs)
971 if (TREE_CODE (*node) != FUNCTION_DECL)
973 warning (OPT_Wattributes, "%qE attribute ignored", name);
974 *no_add_attrs = true;
977 return NULL_TREE;
980 /* Handle a "no_icf" attribute; arguments as in
981 struct attribute_spec.handler. */
983 static tree
984 d_handle_noicf_attribute (tree *node, tree name, tree, int,
985 bool *no_add_attrs)
987 if (TREE_CODE (*node) != FUNCTION_DECL)
989 warning (OPT_Wattributes, "%qE attribute ignored", name);
990 *no_add_attrs = true;
993 return NULL_TREE;
996 /* Handle a "noipa" attribute; arguments as in
997 struct attribute_spec.handler. */
999 static tree
1000 d_handle_noipa_attribute (tree *node, tree name, tree, int,
1001 bool *no_add_attrs)
1003 if (TREE_CODE (*node) != FUNCTION_DECL)
1005 warning (OPT_Wattributes, "%qE attribute ignored", name);
1006 *no_add_attrs = true;
1009 return NULL_TREE;
1012 /* Handle a "section" attribute; arguments as in
1013 struct attribute_spec.handler. */
1015 static tree
1016 d_handle_section_attribute (tree *node, tree name, tree args, int flags,
1017 bool *no_add_attrs)
1019 if (!targetm_common.have_named_sections)
1021 error ("section attributes are not supported for this target");
1022 *no_add_attrs = true;
1023 return NULL_TREE;
1026 if (!VAR_OR_FUNCTION_DECL_P (*node))
1028 error ("section attribute not allowed for %q+D", *node);
1029 *no_add_attrs = true;
1030 return NULL_TREE;
1033 if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
1035 error ("%qE attribute argument not a string constant", name);
1036 *no_add_attrs = true;
1037 return NULL_TREE;
1040 if (VAR_P (*node)
1041 && current_function_decl != NULL_TREE
1042 && !TREE_STATIC (*node))
1044 error ("section attribute cannot be specified for local variables");
1045 *no_add_attrs = true;
1046 return NULL_TREE;
1049 /* The decl may have already been given a section attribute
1050 from a previous declaration. Ensure they match. */
1051 if (DECL_SECTION_NAME (*node) != NULL
1052 && strcmp (DECL_SECTION_NAME (*node),
1053 TREE_STRING_POINTER (TREE_VALUE (args))) != 0)
1055 error ("section of %q+D conflicts with previous declaration", *node);
1056 *no_add_attrs = true;
1057 return NULL_TREE;
1060 if (VAR_P (*node)
1061 && !targetm.have_tls && targetm.emutls.tmpl_section
1062 && DECL_THREAD_LOCAL_P (*node))
1064 error ("section of %q+D cannot be overridden", *node);
1065 *no_add_attrs = true;
1066 return NULL_TREE;
1069 tree res = targetm.handle_generic_attribute (node, name, args, flags,
1070 no_add_attrs);
1072 /* If the back end confirms the attribute can be added then continue onto
1073 final processing. */
1074 if (*no_add_attrs)
1075 return NULL_TREE;
1077 set_decl_section_name (*node, TREE_STRING_POINTER (TREE_VALUE (args)));
1078 return res;
1081 /* Handle a "symver" and attribute; arguments as in
1082 struct attribute_spec.handler. */
1084 static tree
1085 d_handle_symver_attribute (tree *node, tree name, tree args, int,
1086 bool *no_add_attrs)
1088 if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL)
1090 warning (OPT_Wattributes,
1091 "%<symver%> attribute only applies to functions and variables");
1092 *no_add_attrs = true;
1093 return NULL_TREE;
1096 if (!decl_in_symtab_p (*node))
1098 warning (OPT_Wattributes,
1099 "%<symver%> attribute is only applicable to symbols");
1100 *no_add_attrs = true;
1101 return NULL_TREE;
1104 for (; args; args = TREE_CHAIN (args))
1106 tree symver = TREE_VALUE (args);
1107 if (TREE_CODE (symver) != STRING_CST)
1109 error ("%qE attribute argument not a string constant", name);
1110 *no_add_attrs = true;
1111 return NULL_TREE;
1114 const char *symver_str = TREE_STRING_POINTER (symver);
1116 int ats = 0;
1117 for (int n = 0; (int)n < TREE_STRING_LENGTH (symver); n++)
1118 if (symver_str[n] == '@')
1119 ats++;
1121 if (ats != 1 && ats != 2)
1123 error ("symver attribute argument must have format %<name@nodename%>");
1124 error ("%<symver%> attribute argument %qs must contain one or two "
1125 "%<@%>", symver_str);
1126 *no_add_attrs = true;
1127 return NULL_TREE;
1131 return NULL_TREE;
1134 /* Handle a "weak" attribute; arguments as in
1135 struct attribute_spec.handler. */
1137 static tree
1138 d_handle_weak_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
1140 if (TREE_CODE (*node) == FUNCTION_DECL
1141 && DECL_DECLARED_INLINE_P (*node))
1143 warning (OPT_Wattributes, "inline function %q+D declared weak", *node);
1144 *no_add_attrs = true;
1146 else if (VAR_OR_FUNCTION_DECL_P (*node))
1148 struct symtab_node *n = symtab_node::get (*node);
1149 if (n && n->refuse_visibility_changes)
1150 error ("%q+D declared weak after being used", *node);
1151 declare_weak (*node);
1153 else
1154 warning (OPT_Wattributes, "%qE attribute ignored", name);
1156 return NULL_TREE;
1159 /* Handle a "noplt" attribute; arguments as in
1160 struct attribute_spec.handler. */
1162 static tree
1163 d_handle_noplt_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
1165 if (TREE_CODE (*node) != FUNCTION_DECL)
1167 warning (OPT_Wattributes, "%qE attribute ignored", name);
1168 *no_add_attrs = true;
1171 return NULL_TREE;
1174 /* Verify that argument value POS at position ARGNO to attribute ATNAME applied
1175 to function FNTYPE refers to a function parameter at position POS and is a
1176 valid integer type. When ZERO_BASED is true, POS is adjusted to be 1-based.
1177 If successful, POS is returned. Otherwise, issue appropriate warnings and
1178 return null. A non-zero 1-based ARGNO should be passed in by callers only
1179 for attributes with more than one argument. */
1181 static tree
1182 positional_argument (const_tree fntype, const_tree atname, tree pos,
1183 int argno, bool zero_based)
1185 tree postype = TREE_TYPE (pos);
1187 if (pos == error_mark_node || !postype)
1189 /* Only mention the positional argument number when it's non-zero. */
1190 if (argno < 1)
1191 warning (OPT_Wattributes,
1192 "%qE attribute argument is invalid", atname);
1193 else
1194 warning (OPT_Wattributes,
1195 "%qE attribute argument %i is invalid", atname, argno);
1197 return NULL_TREE;
1200 if (!INTEGRAL_TYPE_P (postype))
1202 /* Handle this case specially to avoid mentioning the value
1203 of pointer constants in diagnostics. Only mention
1204 the positional argument number when it's non-zero. */
1205 if (argno < 1)
1206 warning (OPT_Wattributes,
1207 "%qE attribute argument has type %qT",
1208 atname, postype);
1209 else
1210 warning (OPT_Wattributes,
1211 "%qE attribute argument %i has type %qT",
1212 atname, argno, postype);
1214 return NULL_TREE;
1217 if (TREE_CODE (pos) != INTEGER_CST)
1219 /* Only mention the argument number when it's non-zero. */
1220 if (argno < 1)
1221 warning (OPT_Wattributes,
1222 "%qE attribute argument value %qE is not an integer "
1223 "constant",
1224 atname, pos);
1225 else
1226 warning (OPT_Wattributes,
1227 "%qE attribute argument %i value %qE is not an integer "
1228 "constant",
1229 atname, argno, pos);
1231 return NULL_TREE;
1234 /* Validate the value of the position argument. If 0-based, then it should
1235 not be negative. If 1-based, it should be greater than zero. */
1236 if ((zero_based && tree_int_cst_sgn (pos) < 0)
1237 || (!zero_based && tree_int_cst_sgn (pos) < 1))
1239 if (argno < 1)
1240 warning (OPT_Wattributes,
1241 "%qE attribute argument value %qE does not refer to "
1242 "a function parameter",
1243 atname, pos);
1244 else
1245 warning (OPT_Wattributes,
1246 "%qE attribute argument %i value %qE does not refer to "
1247 "a function parameter",
1248 atname, argno, pos);
1250 return NULL_TREE;
1253 /* Adjust the value of pos to be 1-based. */
1254 tree adjusted_pos = (zero_based)
1255 ? int_const_binop (PLUS_EXPR, pos, integer_one_node) : pos;
1257 if (!prototype_p (fntype))
1258 return adjusted_pos;
1260 /* Verify that the argument position does not exceed the number
1261 of formal arguments to the function. */
1262 unsigned nargs = type_num_arguments (fntype);
1263 if (!nargs
1264 || !tree_fits_uhwi_p (adjusted_pos)
1265 || !IN_RANGE (tree_to_uhwi (adjusted_pos), 1, nargs))
1267 if (argno < 1)
1268 warning (OPT_Wattributes,
1269 "%qE attribute argument value %qE exceeds the number "
1270 "of function parameters %u",
1271 atname, pos, nargs);
1272 else
1273 warning (OPT_Wattributes,
1274 "%qE attribute argument %i value %qE exceeds the number "
1275 "of function parameters %u",
1276 atname, argno, pos, nargs);
1278 return NULL_TREE;
1281 /* Verify that the type of the referenced formal argument matches
1282 the expected type. */
1283 unsigned HOST_WIDE_INT ipos = tree_to_uhwi (adjusted_pos);
1285 /* Zero was handled above. */
1286 gcc_assert (ipos != 0);
1288 if (tree argtype = type_argument_type (fntype, ipos))
1290 /* Accept types that match INTEGRAL_TYPE_P except for bool. */
1291 if (!INTEGRAL_TYPE_P (argtype) || TREE_CODE (argtype) == BOOLEAN_TYPE)
1293 if (argno < 1)
1294 warning (OPT_Wattributes,
1295 "%qE attribute argument value %qE refers to "
1296 "parameter type %qT",
1297 atname, pos, argtype);
1298 else
1299 warning (OPT_Wattributes,
1300 "%qE attribute argument %i value %qE refers to "
1301 "parameter type %qT",
1302 atname, argno, pos, argtype);
1304 return NULL_TREE;
1307 return adjusted_pos;
1310 /* Argument position exceeding number of parameters was handled above. */
1311 gcc_unreachable ();
1314 /* Handle a "alloc_size" attribute; arguments as in
1315 struct attribute_spec.handler. */
1317 static tree
1318 d_handle_alloc_size_attribute (tree *node, tree name, tree args, int,
1319 bool *no_add_attrs)
1321 tree fntype = *node;
1322 tree rettype = TREE_TYPE (fntype);
1323 if (!POINTER_TYPE_P (rettype))
1325 warning (OPT_Wattributes,
1326 "%qE attribute ignored on a function returning %qT",
1327 name, rettype);
1328 *no_add_attrs = true;
1329 return NULL_TREE;
1332 /* The first argument SIZE_ARG is never null. */
1333 tree size_arg = TREE_VALUE (args);
1334 tree next = TREE_CHAIN (args);
1336 /* NUM_ARG is null when the attribute includes just one argument, or is
1337 explictly set to null if it has been left uninitialized by the caller. */
1338 tree num_arg = NULL_TREE;
1339 if (next != NULL_TREE)
1341 if (TREE_VALUE (next) != TYPE_MIN_VALUE (d_int_type))
1342 num_arg = TREE_VALUE (next);
1344 next = TREE_CHAIN (next);
1347 /* If ZERO_ARG is set and true, arguments positions are treated as 0-based.
1348 Otherwise the default is 1-based. */
1349 bool zero_based = false;
1350 if (next != NULL_TREE)
1351 zero_based = integer_truep (TREE_VALUE (next));
1353 /* Update the argument values with the real argument position. */
1354 if (tree val = positional_argument (fntype, name, size_arg, num_arg ? 1 : 0,
1355 zero_based))
1356 TREE_VALUE (args) = val;
1357 else
1358 *no_add_attrs = true;
1360 if (num_arg != NULL_TREE)
1362 args = TREE_CHAIN (args);
1363 if (tree val = positional_argument (fntype, name, num_arg, 2, zero_based))
1364 TREE_VALUE (args) = val;
1365 else
1366 *no_add_attrs = true;
1369 /* Terminate the original TREE_CHAIN in `args' to remove any remaining
1370 D-specific `alloc_size` arguments. */
1371 TREE_CHAIN (args) = NULL_TREE;
1373 return NULL_TREE;
1376 /* Handle a "cold" and attribute; arguments as in
1377 struct attribute_spec.handler. */
1379 static tree
1380 d_handle_cold_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
1382 if (TREE_CODE (*node) != FUNCTION_DECL)
1384 warning (OPT_Wattributes, "%qE attribute ignored", name);
1385 *no_add_attrs = true;
1388 return NULL_TREE;
1391 /* Handle a "no_sanitize" attribute; arguments as in
1392 struct attribute_spec.handler. */
1394 static tree
1395 d_handle_no_sanitize_attribute (tree *node, tree name, tree args, int,
1396 bool *no_add_attrs)
1398 *no_add_attrs = true;
1400 if (TREE_CODE (*node) != FUNCTION_DECL)
1402 warning (OPT_Wattributes, "%qE attribute ignored", name);
1403 return NULL_TREE;
1406 unsigned int flags = 0;
1407 for (; args; args = TREE_CHAIN (args))
1409 tree id = TREE_VALUE (args);
1410 if (TREE_CODE (id) != STRING_CST)
1412 error ("%qE attribute argument not a string constant", name);
1413 return NULL_TREE;
1416 char *string = ASTRDUP (TREE_STRING_POINTER (id));
1417 flags |= parse_no_sanitize_attribute (string);
1420 /* Store the flags argument back into no_sanitize attribute as an integer,
1421 merge existing flags if no_sanitize was previously handled. */
1422 if (tree attr = lookup_attribute ("no_sanitize", DECL_ATTRIBUTES (*node)))
1424 unsigned int old_value = tree_to_uhwi (TREE_VALUE (attr));
1425 flags |= old_value;
1427 if (flags != old_value)
1428 TREE_VALUE (attr) = build_int_cst (d_uint_type, flags);
1430 else
1432 DECL_ATTRIBUTES (*node) = tree_cons (get_identifier ("no_sanitize"),
1433 build_int_cst (d_uint_type, flags),
1434 DECL_ATTRIBUTES (*node));
1437 return NULL_TREE;
1440 /* Handle a "register" attribute; arguments as in
1441 struct attribute_spec.handler. */
1443 static tree
1444 d_handle_register_attribute (tree *node, tree name, tree args, int,
1445 bool *no_add_attrs)
1447 if (!VAR_P (*node))
1449 warning (OPT_Wattributes, "%qE attribute ignored", name);
1450 *no_add_attrs = true;
1452 else if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
1454 error ("%qE attribute argument not a string constant", name);
1455 *no_add_attrs = true;
1457 else if (TREE_STRING_LENGTH (TREE_VALUE (args)) == 0
1458 || TREE_STRING_POINTER (TREE_VALUE (args))[0] == '\0')
1460 error ("register name not specified for %q+D", *node);
1461 *no_add_attrs = true;
1463 else
1465 DECL_REGISTER (*node) = 1;
1466 set_user_assembler_name (*node, TREE_STRING_POINTER (TREE_VALUE (args)));
1467 DECL_HARD_REGISTER (*node) = 1;
1470 return NULL_TREE;
1473 /* Handle a "restrict" attribute; arguments as in
1474 struct attribute_spec.handler. */
1476 static tree
1477 d_handle_restrict_attribute (tree *node, tree name, tree, int,
1478 bool *no_add_attrs)
1480 if (TREE_CODE (*node) == PARM_DECL && POINTER_TYPE_P (TREE_TYPE (*node)))
1482 TREE_TYPE (*node) = build_qualified_type (TREE_TYPE (*node),
1483 TYPE_QUAL_RESTRICT);
1485 else
1487 warning (OPT_Wattributes, "%qE attribute ignored", name);
1488 *no_add_attrs = true;
1491 return NULL_TREE;
1494 /* Handle a "simd" attribute; arguments as in
1495 struct attribute_spec.handler. */
1497 static tree
1498 d_handle_simd_attribute (tree *node, tree name, tree args, int,
1499 bool *no_add_attrs)
1501 if (TREE_CODE (*node) != FUNCTION_DECL)
1503 warning (OPT_Wattributes, "%qE attribute ignored", name);
1504 *no_add_attrs = true;
1505 return NULL_TREE;
1508 tree omp_attr = get_identifier ("omp declare simd");
1509 tree omp_flags = NULL_TREE;
1510 if (args)
1512 tree id = TREE_VALUE (args);
1514 if (TREE_CODE (id) != STRING_CST)
1516 error ("%qE attribute argument not a string constant", name);
1517 *no_add_attrs = true;
1518 return NULL_TREE;
1521 if (strcmp (TREE_STRING_POINTER (id), "notinbranch") == 0)
1522 omp_flags = build_omp_clause (DECL_SOURCE_LOCATION (*node),
1523 OMP_CLAUSE_NOTINBRANCH);
1524 else if (strcmp (TREE_STRING_POINTER (id), "inbranch") == 0)
1525 omp_flags = build_omp_clause (DECL_SOURCE_LOCATION (*node),
1526 OMP_CLAUSE_INBRANCH);
1527 else
1529 error ("only %<inbranch%> and %<notinbranch%> flags are "
1530 "allowed for %<simd%> attribute");
1531 *no_add_attrs = true;
1532 return NULL_TREE;
1536 DECL_ATTRIBUTES (*node) =
1537 tree_cons (omp_attr, build_tree_list (NULL_TREE, omp_flags),
1538 DECL_ATTRIBUTES (*node));
1540 return NULL_TREE;
1543 /* Handle a "used" attribute; arguments as in
1544 struct attribute_spec.handler. */
1546 static tree
1547 d_handle_used_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
1549 if (TREE_CODE (*node) == FUNCTION_DECL
1550 || (VAR_P (*node) && TREE_STATIC (*node))
1551 || (TREE_CODE (*node) == TYPE_DECL))
1553 TREE_USED (*node) = 1;
1554 DECL_PRESERVE_P (*node) = 1;
1555 if (VAR_P (*node))
1556 DECL_READ_P (*node) = 1;
1558 else
1560 warning (OPT_Wattributes, "%qE attribute ignored", name);
1561 *no_add_attrs = true;
1564 return NULL_TREE;
1567 /* Handle an "visibility" attribute; arguments as in
1568 struct attribute_spec.handler. */
1570 static tree
1571 d_handle_visibility_attribute (tree *node, tree name, tree args,
1572 int, bool *)
1574 /* If this is a type, set the visibility on the type decl. */
1575 tree decl = *node;
1576 if (TYPE_P (decl))
1578 decl = TYPE_NAME (decl);
1579 if (decl == NULL_TREE || TREE_CODE (decl) != TYPE_DECL)
1581 warning (OPT_Wattributes, "%qE attribute ignored on types", name);
1582 return NULL_TREE;
1586 if (decl_function_context (decl) != 0 || !TREE_PUBLIC (decl))
1588 warning (OPT_Wattributes, "%qE attribute ignored", name);
1589 return NULL_TREE;
1592 tree id = TREE_VALUE (args);
1593 if (TREE_CODE (id) != STRING_CST)
1595 error ("%qE attribute argument not a string constant", name);
1596 return NULL_TREE;
1599 enum symbol_visibility vis;
1600 if (strcmp (TREE_STRING_POINTER (id), "default") == 0)
1601 vis = VISIBILITY_DEFAULT;
1602 else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0)
1603 vis = VISIBILITY_INTERNAL;
1604 else if (strcmp (TREE_STRING_POINTER (id), "hidden") == 0)
1605 vis = VISIBILITY_HIDDEN;
1606 else if (strcmp (TREE_STRING_POINTER (id), "protected") == 0)
1607 vis = VISIBILITY_PROTECTED;
1608 else
1610 error ("attribute %qE argument must be one of %qs, %qs, %qs, or %qs",
1611 name, "default", "hidden", "protected", "internal");
1612 vis = VISIBILITY_DEFAULT;
1615 if (DECL_VISIBILITY_SPECIFIED (decl) && vis != DECL_VISIBILITY (decl))
1617 tree attributes = (TYPE_P (*node)
1618 ? TYPE_ATTRIBUTES (*node)
1619 : DECL_ATTRIBUTES (decl));
1620 if (lookup_attribute ("visibility", attributes))
1621 error ("%qD redeclared with different visibility", decl);
1622 else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
1623 && lookup_attribute ("dllimport", attributes))
1624 error ("%qD was declared %qs which implies default visibility",
1625 decl, "export");
1626 else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
1627 && lookup_attribute ("dllexport", attributes))
1628 error ("%qD was declared %qs which implies default visibility",
1629 decl, "export");
1632 DECL_VISIBILITY (decl) = vis;
1633 DECL_VISIBILITY_SPECIFIED (decl) = 1;
1635 /* Go ahead and attach the attribute to the node as well. This is needed
1636 so we can determine whether we have VISIBILITY_DEFAULT because the
1637 visibility was not specified, or because it was explicitly overridden
1638 from the containing scope. */
1640 return NULL_TREE;