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)
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. */
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"
33 #include "diagnostic.h"
38 #include "common/common-target.h"
39 #include "stringpool.h"
42 #include "fold-const.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. */
249 insert_type_attribute (tree type
, const char *attrname
, tree value
)
251 tree ident
= get_identifier (attrname
);
254 value
= tree_cons (NULL_TREE
, value
, NULL_TREE
);
256 decl_attributes (&type
, build_tree_list (ident
, value
),
257 ATTR_FLAG_TYPE_IN_PLACE
);
261 /* Insert the decl attribute ATTRNAME with value VALUE into DECL. */
264 insert_decl_attribute (tree decl
, const char *attrname
, tree value
)
266 tree ident
= get_identifier (attrname
);
269 value
= tree_cons (NULL_TREE
, value
, NULL_TREE
);
271 decl_attributes (&decl
, build_tree_list (ident
, value
), 0);
276 /* Returns TRUE if NAME is an attribute recognized as being handled by
277 the `gcc.attribute' module. */
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
)
292 if (targetm
.attribute_table
)
294 for (const attribute_spec
*p
= targetm
.attribute_table
; p
->name
; p
++)
296 if (get_identifier (p
->name
) == ident
)
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. */
315 build_attributes (Expressions
*eattrs
)
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);
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
)
338 sym
= te
->td
->onemember
;
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
))
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 ()));
364 /* Should now have a struct `Attribute("attrib", "value", ...)'
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());
376 StringExp
*se
= e0
->toStringExp ();
377 gcc_assert (se
->sz
== 1);
379 /* Empty string attribute, just ignore it. */
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
);
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. */
403 StringExp
*s
= e
->isStringExp ();
405 if (s
!= NULL
&& s
->sz
== 1)
407 const char *string
= (const char *)(s
->len
? s
->string
: "");
408 t
= build_string (s
->len
, string
);
413 args
= chainon (args
, build_tree_list (0, t
));
416 tree list
= build_tree_list (get_identifier (name
), args
);
417 attribs
= chainon (attribs
, list
);
423 /* If any GCC attributes are found in the declaration SYM, apply them to the
424 type or decl NODE. */
427 apply_user_attributes (Dsymbol
*sym
, tree node
)
429 UserAttributeDeclaration
*uda
= sym
->userAttribDecl ();
433 location_t saved_location
= input_location
;
434 input_location
= make_location_t (sym
->loc
);
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. */
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
)
464 (build_type_variant (TREE_TYPE (type
),
465 TYPE_READONLY (TREE_TYPE (type
)), 1));
472 /* Handle a "leaf" attribute; arguments as in
473 struct attribute_spec.handler. */
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;
492 /* Handle a "const" attribute; arguments as in
493 struct attribute_spec.handler. */
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
)
506 (build_type_variant (TREE_TYPE (type
), 1,
507 TREE_THIS_VOLATILE (TREE_TYPE (type
))));
514 /* Handle a "malloc" attribute; arguments as in
515 struct attribute_spec.handler. */
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;
526 /* Handle a "pure" attribute; arguments as in
527 struct attribute_spec.handler. */
530 handle_pure_attribute (tree
*node
, tree
, tree
, int, bool *)
532 gcc_assert (TREE_CODE (*node
) == FUNCTION_DECL
);
533 DECL_PURE_P (*node
) = 1;
537 /* Handle a "no vops" attribute; arguments as in
538 struct attribute_spec.handler. */
541 handle_novops_attribute (tree
*node
, tree
, tree
, int, bool *)
543 gcc_assert (TREE_CODE (*node
) == FUNCTION_DECL
);
544 DECL_IS_NOVOPS (*node
) = 1;
548 /* Helper for nonnull attribute handling; fetch the operand number
549 from the attribute argument list. */
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
))
558 *valp
= TREE_INT_CST_LOW (arg_num_expr
);
562 /* Handle the "nonnull" attribute. */
565 handle_nonnull_attribute (tree
*node
, tree
, tree args
, int, bool *)
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
576 gcc_assert (prototype_p (type
)
577 || !TYPE_ATTRIBUTES (type
)
578 || lookup_attribute ("type generic", TYPE_ATTRIBUTES (type
)));
583 /* Argument list specified. Verify that each argument number references
584 a pointer argument. */
585 for (; args
; args
= TREE_CHAIN (args
))
588 unsigned HOST_WIDE_INT arg_num
= 0, ck_num
;
590 if (!get_nonnull_operand (TREE_VALUE (args
), &arg_num
))
593 argument
= TYPE_ARG_TYPES (type
);
596 for (ck_num
= 1; ; ck_num
++)
598 if (!argument
|| ck_num
== arg_num
)
600 argument
= TREE_CHAIN (argument
);
604 && TREE_CODE (TREE_VALUE (argument
)) == POINTER_TYPE
);
611 /* Handle a "nothrow" attribute; arguments as in
612 struct attribute_spec.handler. */
615 handle_nothrow_attribute (tree
*node
, tree
, tree
, int, bool *)
617 gcc_assert (TREE_CODE (*node
) == FUNCTION_DECL
);
618 TREE_NOTHROW (*node
) = 1;
622 /* Handle a "type generic" attribute; arguments as in
623 struct attribute_spec.handler. */
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
));
637 /* Handle a "transaction_pure" attribute; arguments as in
638 struct attribute_spec.handler. */
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
);
649 /* Handle a "returns_twice" attribute; arguments as in
650 struct attribute_spec.handler. */
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;
662 /* Handle a "fn spec" attribute; arguments as in
663 struct attribute_spec.handler. */
666 handle_fnspec_attribute (tree
*, tree
, tree args
, int, bool *)
669 && TREE_CODE (TREE_VALUE (args
)) == STRING_CST
670 && !TREE_CHAIN (args
));
674 /* Handle an "omp declare simd" attribute; arguments as in
675 struct attribute_spec.handler. */
678 handle_omp_declare_simd_attribute (tree
*node
, tree
, tree
, int, bool *)
680 gcc_assert (TREE_CODE (*node
) == FUNCTION_DECL
);
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. */
692 d_handle_noinline_attribute (tree
*node
, tree name
, tree
, int,
695 if (TREE_CODE (*node
) == FUNCTION_DECL
)
696 DECL_UNINLINABLE (*node
) = 1;
699 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
700 *no_add_attrs
= true;
706 /* Handle a "always_inline" attribute; arguments as in
707 struct attribute_spec.handler. */
710 d_handle_always_inline_attribute (tree
*node
, tree name
, tree
, int,
713 if (TREE_CODE (*node
) == FUNCTION_DECL
)
715 DECL_DECLARED_INLINE_P (*node
) = 1;
716 DECL_DISREGARD_INLINE_LIMITS (*node
) = 1;
720 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
721 *no_add_attrs
= true;
727 /* Handle a "flatten" attribute; arguments as in
728 struct attribute_spec.handler. */
731 d_handle_flatten_attribute (tree
*node
, tree name
, tree
, int,
734 if (TREE_CODE (*node
) != FUNCTION_DECL
)
736 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
737 *no_add_attrs
= true;
743 /* Handle a "target" attribute; arguments as in
744 struct attribute_spec.handler. */
747 d_handle_target_attribute (tree
*node
, tree name
, tree args
, int flags
,
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'))
768 warning (OPT_Wattributes
, "empty string in attribute %<target%>");
769 *no_add_attrs
= true;
775 /* Handle a "target_clones" attribute; arguments as in
776 struct attribute_spec.handler. */
779 d_handle_target_clones_attribute (tree
*node
, tree name
, tree
, int,
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;
790 /* Do not inline functions with multiple clone targets. */
791 DECL_UNINLINABLE (*node
) = 1;
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
804 parse_optimize_options (tree args
)
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
)
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
830 if (*p
== '-' && p
[1] != 'O' && p
[1] != 'f')
833 warning (OPT_Wattributes
,
834 "bad option %qs to attribute %<optimize%>", p
);
838 /* Can't use GC memory here. */
839 char *q
= XOBNEWVEC (&opts_obstack
, char, len
+ 3);
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'))
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
,
873 &decoded_options_count
);
874 /* Drop non-Optimization options. */
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
))
883 warning (OPT_Wattributes
,
884 "bad option %qs to attribute %<optimize%>",
885 decoded_options
[i
].orig_option_with_args_text
);
889 decoded_options
[j
] = decoded_options
[i
];
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);
904 /* Handle a "optimize" attribute; arguments as in
905 struct attribute_spec.handler. */
908 d_handle_optimize_attribute (tree
*node
, tree name
, tree args
, int,
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;
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
929 gcc_options
*saved_global_options
= NULL
;
932 saved_global_options
= XNEW (gcc_options
);
933 *saved_global_options
= global_options
;
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
,
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
);
964 /* Handle a "noclone" attribute; arguments as in
965 struct attribute_spec.handler. */
968 d_handle_noclone_attribute (tree
*node
, tree name
, tree
, int,
971 if (TREE_CODE (*node
) != FUNCTION_DECL
)
973 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
974 *no_add_attrs
= true;
980 /* Handle a "no_icf" attribute; arguments as in
981 struct attribute_spec.handler. */
984 d_handle_noicf_attribute (tree
*node
, tree name
, tree
, int,
987 if (TREE_CODE (*node
) != FUNCTION_DECL
)
989 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
990 *no_add_attrs
= true;
996 /* Handle a "noipa" attribute; arguments as in
997 struct attribute_spec.handler. */
1000 d_handle_noipa_attribute (tree
*node
, tree name
, tree
, int,
1003 if (TREE_CODE (*node
) != FUNCTION_DECL
)
1005 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
1006 *no_add_attrs
= true;
1012 /* Handle a "section" attribute; arguments as in
1013 struct attribute_spec.handler. */
1016 d_handle_section_attribute (tree
*node
, tree name
, tree args
, int flags
,
1019 if (!targetm_common
.have_named_sections
)
1021 error ("section attributes are not supported for this target");
1022 *no_add_attrs
= true;
1026 if (!VAR_OR_FUNCTION_DECL_P (*node
))
1028 error ("section attribute not allowed for %q+D", *node
);
1029 *no_add_attrs
= true;
1033 if (TREE_CODE (TREE_VALUE (args
)) != STRING_CST
)
1035 error ("%qE attribute argument not a string constant", name
);
1036 *no_add_attrs
= true;
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;
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;
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;
1069 tree res
= targetm
.handle_generic_attribute (node
, name
, args
, flags
,
1072 /* If the back end confirms the attribute can be added then continue onto
1073 final processing. */
1077 set_decl_section_name (*node
, TREE_STRING_POINTER (TREE_VALUE (args
)));
1081 /* Handle a "symver" and attribute; arguments as in
1082 struct attribute_spec.handler. */
1085 d_handle_symver_attribute (tree
*node
, tree name
, tree args
, int,
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;
1096 if (!decl_in_symtab_p (*node
))
1098 warning (OPT_Wattributes
,
1099 "%<symver%> attribute is only applicable to symbols");
1100 *no_add_attrs
= true;
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;
1114 const char *symver_str
= TREE_STRING_POINTER (symver
);
1117 for (int n
= 0; (int)n
< TREE_STRING_LENGTH (symver
); n
++)
1118 if (symver_str
[n
] == '@')
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;
1134 /* Handle a "weak" attribute; arguments as in
1135 struct attribute_spec.handler. */
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
);
1154 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
1159 /* Handle a "noplt" attribute; arguments as in
1160 struct attribute_spec.handler. */
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;
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. */
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. */
1191 warning (OPT_Wattributes
,
1192 "%qE attribute argument is invalid", atname
);
1194 warning (OPT_Wattributes
,
1195 "%qE attribute argument %i is invalid", atname
, argno
);
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. */
1206 warning (OPT_Wattributes
,
1207 "%qE attribute argument has type %qT",
1210 warning (OPT_Wattributes
,
1211 "%qE attribute argument %i has type %qT",
1212 atname
, argno
, postype
);
1217 if (TREE_CODE (pos
) != INTEGER_CST
)
1219 /* Only mention the argument number when it's non-zero. */
1221 warning (OPT_Wattributes
,
1222 "%qE attribute argument value %qE is not an integer "
1226 warning (OPT_Wattributes
,
1227 "%qE attribute argument %i value %qE is not an integer "
1229 atname
, argno
, pos
);
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))
1240 warning (OPT_Wattributes
,
1241 "%qE attribute argument value %qE does not refer to "
1242 "a function parameter",
1245 warning (OPT_Wattributes
,
1246 "%qE attribute argument %i value %qE does not refer to "
1247 "a function parameter",
1248 atname
, argno
, pos
);
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
);
1264 || !tree_fits_uhwi_p (adjusted_pos
)
1265 || !IN_RANGE (tree_to_uhwi (adjusted_pos
), 1, nargs
))
1268 warning (OPT_Wattributes
,
1269 "%qE attribute argument value %qE exceeds the number "
1270 "of function parameters %u",
1271 atname
, pos
, nargs
);
1273 warning (OPT_Wattributes
,
1274 "%qE attribute argument %i value %qE exceeds the number "
1275 "of function parameters %u",
1276 atname
, argno
, pos
, nargs
);
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
)
1294 warning (OPT_Wattributes
,
1295 "%qE attribute argument value %qE refers to "
1296 "parameter type %qT",
1297 atname
, pos
, argtype
);
1299 warning (OPT_Wattributes
,
1300 "%qE attribute argument %i value %qE refers to "
1301 "parameter type %qT",
1302 atname
, argno
, pos
, argtype
);
1307 return adjusted_pos
;
1310 /* Argument position exceeding number of parameters was handled above. */
1314 /* Handle a "alloc_size" attribute; arguments as in
1315 struct attribute_spec.handler. */
1318 d_handle_alloc_size_attribute (tree
*node
, tree name
, tree args
, int,
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",
1328 *no_add_attrs
= true;
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,
1356 TREE_VALUE (args
) = val
;
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
;
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
;
1376 /* Handle a "cold" and attribute; arguments as in
1377 struct attribute_spec.handler. */
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;
1391 /* Handle a "no_sanitize" attribute; arguments as in
1392 struct attribute_spec.handler. */
1395 d_handle_no_sanitize_attribute (tree
*node
, tree name
, tree args
, int,
1398 *no_add_attrs
= true;
1400 if (TREE_CODE (*node
) != FUNCTION_DECL
)
1402 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
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
);
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
));
1427 if (flags
!= old_value
)
1428 TREE_VALUE (attr
) = build_int_cst (d_uint_type
, flags
);
1432 DECL_ATTRIBUTES (*node
) = tree_cons (get_identifier ("no_sanitize"),
1433 build_int_cst (d_uint_type
, flags
),
1434 DECL_ATTRIBUTES (*node
));
1440 /* Handle a "register" attribute; arguments as in
1441 struct attribute_spec.handler. */
1444 d_handle_register_attribute (tree
*node
, tree name
, tree args
, int,
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;
1465 DECL_REGISTER (*node
) = 1;
1466 set_user_assembler_name (*node
, TREE_STRING_POINTER (TREE_VALUE (args
)));
1467 DECL_HARD_REGISTER (*node
) = 1;
1473 /* Handle a "restrict" attribute; arguments as in
1474 struct attribute_spec.handler. */
1477 d_handle_restrict_attribute (tree
*node
, tree name
, tree
, int,
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
);
1487 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
1488 *no_add_attrs
= true;
1494 /* Handle a "simd" attribute; arguments as in
1495 struct attribute_spec.handler. */
1498 d_handle_simd_attribute (tree
*node
, tree name
, tree args
, int,
1501 if (TREE_CODE (*node
) != FUNCTION_DECL
)
1503 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
1504 *no_add_attrs
= true;
1508 tree omp_attr
= get_identifier ("omp declare simd");
1509 tree omp_flags
= NULL_TREE
;
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;
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
);
1529 error ("only %<inbranch%> and %<notinbranch%> flags are "
1530 "allowed for %<simd%> attribute");
1531 *no_add_attrs
= true;
1536 DECL_ATTRIBUTES (*node
) =
1537 tree_cons (omp_attr
, build_tree_list (NULL_TREE
, omp_flags
),
1538 DECL_ATTRIBUTES (*node
));
1543 /* Handle a "used" attribute; arguments as in
1544 struct attribute_spec.handler. */
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;
1556 DECL_READ_P (*node
) = 1;
1560 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
1561 *no_add_attrs
= true;
1567 /* Handle an "visibility" attribute; arguments as in
1568 struct attribute_spec.handler. */
1571 d_handle_visibility_attribute (tree
*node
, tree name
, tree args
,
1574 /* If this is a type, set the visibility on the type 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
);
1586 if (decl_function_context (decl
) != 0 || !TREE_PUBLIC (decl
))
1588 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
1592 tree id
= TREE_VALUE (args
);
1593 if (TREE_CODE (id
) != STRING_CST
)
1595 error ("%qE attribute argument not a string constant", name
);
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
;
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",
1626 else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
1627 && lookup_attribute ("dllexport", attributes
))
1628 error ("%qD was declared %qs which implies default visibility",
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. */