d: Add `@visibility' and `@hidden' attributes.
[official-gcc.git] / gcc / d / d-attribs.cc
blob4c6e7a7a4bd9af403c6e040e423ba359e24a0602
1 /* d-attribs.c -- D attributes handling.
2 Copyright (C) 2015-2022 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 *);
62 /* D attribute handlers for user defined attributes. */
63 static tree d_handle_noinline_attribute (tree *, tree, tree, int, bool *);
64 static tree d_handle_always_inline_attribute (tree *, tree, tree, int, bool *);
65 static tree d_handle_flatten_attribute (tree *, tree, tree, int, bool *);
66 static tree d_handle_target_attribute (tree *, tree, tree, int, bool *);
67 static tree d_handle_target_clones_attribute (tree *, tree, tree, int, bool *);
68 static tree d_handle_optimize_attribute (tree *, tree, tree, int, bool *);
69 static tree d_handle_noclone_attribute (tree *, tree, tree, int, bool *);
70 static tree d_handle_noicf_attribute (tree *, tree, tree, int, bool *);
71 static tree d_handle_noipa_attribute (tree *, tree, tree, int, bool *);
72 static tree d_handle_section_attribute (tree *, tree, tree, int, bool *);
73 static tree d_handle_symver_attribute (tree *, tree, tree, int, bool *);
74 static tree d_handle_weak_attribute (tree *, tree, tree, int, bool *) ;
75 static tree d_handle_noplt_attribute (tree *, tree, tree, int, bool *) ;
76 static tree d_handle_alloc_size_attribute (tree *, tree, tree, int, bool *);
77 static tree d_handle_cold_attribute (tree *, tree, tree, int, bool *);
78 static tree d_handle_restrict_attribute (tree *, tree, tree, int, bool *);
79 static tree d_handle_used_attribute (tree *, tree, tree, int, bool *);
80 static tree d_handle_visibility_attribute (tree *, tree, tree, int, bool *);
82 /* Helper to define attribute exclusions. */
83 #define ATTR_EXCL(name, function, type, variable) \
84 { name, function, type, variable }
86 /* Define attributes that are mutually exclusive with one another. */
87 static const struct attribute_spec::exclusions attr_noreturn_exclusions[] =
89 ATTR_EXCL ("alloc_size", true, true, true),
90 ATTR_EXCL ("const", true, true, true),
91 ATTR_EXCL ("malloc", true, true, true),
92 ATTR_EXCL ("pure", true, true, true),
93 ATTR_EXCL ("returns_twice", true, true, true),
94 ATTR_EXCL (NULL, false, false, false),
97 static const struct attribute_spec::exclusions attr_returns_twice_exclusions[] =
99 ATTR_EXCL ("noreturn", true, true, true),
100 ATTR_EXCL (NULL, false, false, false),
103 static const struct attribute_spec::exclusions attr_const_pure_exclusions[] =
105 ATTR_EXCL ("alloc_size", true, true, true),
106 ATTR_EXCL ("const", true, true, true),
107 ATTR_EXCL ("noreturn", true, true, true),
108 ATTR_EXCL ("pure", true, true, true),
109 ATTR_EXCL (NULL, false, false, false)
112 static const struct attribute_spec::exclusions attr_inline_exclusions[] =
114 ATTR_EXCL ("noinline", true, true, true),
115 ATTR_EXCL ("target_clones", true, true, true),
116 ATTR_EXCL (NULL, false, false, false),
119 static const struct attribute_spec::exclusions attr_noinline_exclusions[] =
121 ATTR_EXCL ("always_inline", true, true, true),
122 ATTR_EXCL (NULL, false, false, false),
125 static const struct attribute_spec::exclusions attr_target_exclusions[] =
127 ATTR_EXCL ("target_clones", true, true, true),
128 ATTR_EXCL (NULL, false, false, false),
131 static const struct attribute_spec::exclusions attr_target_clones_exclusions[] =
133 ATTR_EXCL ("always_inline", true, true, true),
134 ATTR_EXCL ("target", true, true, true),
135 ATTR_EXCL (NULL, false, false, false),
138 static const struct attribute_spec::exclusions attr_alloc_exclusions[] =
140 ATTR_EXCL ("const", true, true, true),
141 ATTR_EXCL ("noreturn", true, true, true),
142 ATTR_EXCL ("pure", true, true, true),
143 ATTR_EXCL (NULL, false, false, false),
146 extern const struct attribute_spec::exclusions attr_cold_hot_exclusions[] =
148 ATTR_EXCL ("cold", true, true, true),
149 ATTR_EXCL ("hot", true, true, true),
150 ATTR_EXCL (NULL, false, false, false)
153 /* Helper to define an attribute. */
154 #define ATTR_SPEC(name, min_len, max_len, decl_req, type_req, fn_type_req, \
155 affects_type_identity, handler, exclude) \
156 { name, min_len, max_len, decl_req, type_req, fn_type_req, \
157 affects_type_identity, handler, exclude }
159 /* Table of machine-independent attributes.
160 For internal use (marking of built-ins) only. */
161 const attribute_spec d_langhook_common_attribute_table[] =
163 ATTR_SPEC ("noreturn", 0, 0, true, false, false, false,
164 handle_noreturn_attribute, attr_noreturn_exclusions),
165 ATTR_SPEC ("leaf", 0, 0, true, false, false, false,
166 handle_leaf_attribute, NULL),
167 ATTR_SPEC ("const", 0, 0, true, false, false, false,
168 handle_const_attribute, attr_const_pure_exclusions),
169 ATTR_SPEC ("malloc", 0, 0, true, false, false, false,
170 handle_malloc_attribute, NULL),
171 ATTR_SPEC ("returns_twice", 0, 0, true, false, false, false,
172 handle_returns_twice_attribute, attr_returns_twice_exclusions),
173 ATTR_SPEC ("pure", 0, 0, true, false, false, false,
174 handle_pure_attribute, attr_const_pure_exclusions),
175 ATTR_SPEC ("nonnull", 0, -1, false, true, true, false,
176 handle_nonnull_attribute, NULL),
177 ATTR_SPEC ("nothrow", 0, 0, true, false, false, false,
178 handle_nothrow_attribute, NULL),
179 ATTR_SPEC ("transaction_pure", 0, 0, false, true, true, false,
180 handle_transaction_pure_attribute, NULL),
181 ATTR_SPEC ("no vops", 0, 0, true, false, false, false,
182 handle_novops_attribute, NULL),
183 ATTR_SPEC ("type generic", 0, 0, false, true, true, false,
184 handle_type_generic_attribute, NULL),
185 ATTR_SPEC ("fn spec", 1, 1, false, true, true, false,
186 handle_fnspec_attribute, NULL),
187 ATTR_SPEC (NULL, 0, 0, false, false, false, false, NULL, NULL),
190 /* Table of D language attributes exposed by `gcc.attribute' UDAs. */
191 const attribute_spec d_langhook_attribute_table[] =
193 ATTR_SPEC ("noinline", 0, 0, true, false, false, false,
194 d_handle_noinline_attribute, attr_noinline_exclusions),
195 ATTR_SPEC ("always_inline", 0, 0, true, false, false, false,
196 d_handle_always_inline_attribute, attr_inline_exclusions),
197 ATTR_SPEC ("flatten", 0, 0, true, false, false, false,
198 d_handle_flatten_attribute, NULL),
199 ATTR_SPEC ("target", 1, -1, true, false, false, false,
200 d_handle_target_attribute, attr_target_exclusions),
201 ATTR_SPEC ("target_clones", 1, -1, true, false, false, false,
202 d_handle_target_clones_attribute, attr_target_clones_exclusions),
203 ATTR_SPEC ("optimize", 1, -1, true, false, false, false,
204 d_handle_optimize_attribute, NULL),
205 ATTR_SPEC ("noclone", 0, 0, true, false, false, false,
206 d_handle_noclone_attribute, NULL),
207 ATTR_SPEC ("no_icf", 0, 0, true, false, false, false,
208 d_handle_noicf_attribute, NULL),
209 ATTR_SPEC ("noipa", 0, 0, true, false, false, false,
210 d_handle_noipa_attribute, NULL),
211 ATTR_SPEC ("section", 1, 1, true, false, false, false,
212 d_handle_section_attribute, NULL),
213 ATTR_SPEC ("symver", 1, -1, true, false, false, false,
214 d_handle_symver_attribute, NULL),
215 ATTR_SPEC ("weak", 0, 0, true, false, false, false,
216 d_handle_weak_attribute, NULL),
217 ATTR_SPEC ("noplt", 0, 0, true, false, false, false,
218 d_handle_noplt_attribute, NULL),
219 ATTR_SPEC ("alloc_size", 1, 3, false, true, true, false,
220 d_handle_alloc_size_attribute, attr_alloc_exclusions),
221 ATTR_SPEC ("cold", 0, 0, true, false, false, false,
222 d_handle_cold_attribute, attr_cold_hot_exclusions),
223 ATTR_SPEC ("restrict", 0, 0, true, false, false, false,
224 d_handle_restrict_attribute, NULL),
225 ATTR_SPEC ("used", 0, 0, true, false, false, false,
226 d_handle_used_attribute, NULL),
227 ATTR_SPEC ("visibility", 1, 1, false, false, false, false,
228 d_handle_visibility_attribute, NULL),
229 ATTR_SPEC (NULL, 0, 0, false, false, false, false, NULL, NULL),
233 /* Insert the type attribute ATTRNAME with value VALUE into TYPE.
234 Returns a new variant of the original type declaration. */
236 tree
237 insert_type_attribute (tree type, const char *attrname, tree value)
239 tree ident = get_identifier (attrname);
241 if (value)
242 value = tree_cons (NULL_TREE, value, NULL_TREE);
244 decl_attributes (&type, build_tree_list (ident, value),
245 ATTR_FLAG_TYPE_IN_PLACE);
246 return type;
249 /* Insert the decl attribute ATTRNAME with value VALUE into DECL. */
251 tree
252 insert_decl_attribute (tree decl, const char *attrname, tree value)
254 tree ident = get_identifier (attrname);
256 if (value)
257 value = tree_cons (NULL_TREE, value, NULL_TREE);
259 decl_attributes (&decl, build_tree_list (ident, value), 0);
261 return decl;
264 /* Returns TRUE if NAME is an attribute recognized as being handled by
265 the `gcc.attribute' module. */
267 static bool
268 uda_attribute_p (const char *name)
270 tree ident = get_identifier (name);
272 /* Search both our language, and target attribute tables.
273 Common and format attributes are kept internal. */
274 for (const attribute_spec *p = d_langhook_attribute_table; p->name; p++)
276 if (get_identifier (p->name) == ident)
277 return true;
280 if (targetm.attribute_table)
282 for (const attribute_spec *p = targetm.attribute_table; p->name; p++)
284 if (get_identifier (p->name) == ident)
285 return true;
289 return false;
292 /* [attribute/uda]
294 User Defined Attributes (UDA) are compile time expressions that can be
295 attached to a declaration. These attributes can then be queried, extracted,
296 and manipulated at compile-time. There is no run-time component to them.
298 Expand and merge all UDAs found in the EATTRS list that are of type
299 `gcc.attribute.Attribute'. This symbol is internally recognized by the
300 compiler and maps them to their equivalent GCC attribute. */
302 static tree
303 build_attributes (Expressions *eattrs)
305 if (!eattrs)
306 return NULL_TREE;
308 expandTuples (eattrs);
310 tree attribs = NULL_TREE;
312 for (size_t i = 0; i < eattrs->length; i++)
314 Expression *attr = (*eattrs)[i];
315 Dsymbol *sym = attr->type->toDsymbol (0);
317 if (!sym)
319 /* If attribute is a template symbol, perhaps arguments were not
320 supplied, so warn about attribute having no effect. */
321 if (TemplateExp *te = attr->isTemplateExp ())
323 if (!te->td || !te->td->onemember)
324 continue;
326 sym = te->td->onemember;
328 else
329 continue;
332 /* Attribute symbol must come from the `gcc.attribute' module. */
333 Dsymbol *mod = sym->getModule ();
334 if (!(strcmp (mod->toChars (), "attributes") == 0
335 && mod->parent != NULL
336 && strcmp (mod->parent->toChars (), "gcc") == 0
337 && !mod->parent->parent))
338 continue;
340 /* Get the result of the attribute if it hasn't already been folded. */
341 if (attr->op == EXP::call)
342 attr = attr->ctfeInterpret ();
344 if (attr->op != EXP::structLiteral)
346 warning_at (make_location_t (attr->loc), OPT_Wattributes,
347 "%qE attribute has no effect",
348 get_identifier (sym->toChars ()));
349 continue;
352 /* Should now have a struct `Attribute("attrib", "value", ...)'
353 initializer list. */
354 Expressions *elems = attr->isStructLiteralExp ()->elements;
355 Expression *e0 = (*elems)[0];
357 if (e0->op != EXP::string_)
359 warning_at (make_location_t (attr->loc), OPT_Wattributes,
360 "unknown attribute %qs", e0->toChars());
361 continue;
364 StringExp *se = e0->toStringExp ();
365 gcc_assert (se->sz == 1);
367 /* Empty string attribute, just ignore it. */
368 if (se->len == 0)
369 continue;
371 /* Check if the attribute is recognized and handled.
372 Done here to report the diagnostic at the right location. */
373 const char *name = (const char *)(se->len ? se->string : "");
374 if (!uda_attribute_p (name))
376 warning_at (make_location_t (attr->loc), OPT_Wattributes,
377 "unknown attribute %qs", name);
378 continue;
381 /* Chain all attribute arguments together. */
382 tree args = NULL_TREE;
384 for (size_t j = 1; j < elems->length; j++)
386 Expression *e = (*elems)[j];
387 /* Stop after the first `void' argument. */
388 if (e == NULL)
389 break;
391 StringExp *s = e->isStringExp ();
392 tree t;
393 if (s != NULL && s->sz == 1)
395 const char *string = (const char *)(s->len ? s->string : "");
396 t = build_string (s->len, string);
398 else
399 t = build_expr (e);
401 args = chainon (args, build_tree_list (0, t));
404 tree list = build_tree_list (get_identifier (name), args);
405 attribs = chainon (attribs, list);
408 return attribs;
411 /* If any GCC attributes are found in the declaration SYM, apply them to the
412 type or decl NODE. */
414 void
415 apply_user_attributes (Dsymbol *sym, tree node)
417 if (!sym->userAttribDecl)
418 return;
420 location_t saved_location = input_location;
421 input_location = make_location_t (sym->loc);
423 int attr_flags = 0;
424 if (TYPE_P (node) && !COMPLETE_TYPE_P (node))
425 attr_flags |= ATTR_FLAG_TYPE_IN_PLACE;
427 Expressions *attrs = sym->userAttribDecl->getAttributes ();
428 decl_attributes (&node, build_attributes (attrs), attr_flags);
430 input_location = saved_location;
433 /* Built-in attribute handlers.
434 These functions take the arguments:
435 (tree *node, tree name, tree args, int flags, bool *no_add_attrs) */
437 /* Handle a "noreturn" attribute; arguments as in
438 struct attribute_spec.handler. */
440 static tree
441 handle_noreturn_attribute (tree *node, tree, tree, int, bool *)
443 tree type = TREE_TYPE (*node);
445 if (TREE_CODE (*node) == FUNCTION_DECL)
446 TREE_THIS_VOLATILE (*node) = 1;
447 else if (TREE_CODE (type) == POINTER_TYPE
448 && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
449 TREE_TYPE (*node)
450 = build_pointer_type
451 (build_type_variant (TREE_TYPE (type),
452 TYPE_READONLY (TREE_TYPE (type)), 1));
453 else
454 gcc_unreachable ();
456 return NULL_TREE;
459 /* Handle a "leaf" attribute; arguments as in
460 struct attribute_spec.handler. */
462 static tree
463 handle_leaf_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
465 if (TREE_CODE (*node) != FUNCTION_DECL)
467 warning (OPT_Wattributes, "%qE attribute ignored", name);
468 *no_add_attrs = true;
470 if (!TREE_PUBLIC (*node))
472 warning (OPT_Wattributes, "%qE attribute has no effect", name);
473 *no_add_attrs = true;
476 return NULL_TREE;
479 /* Handle a "const" attribute; arguments as in
480 struct attribute_spec.handler. */
482 static tree
483 handle_const_attribute (tree *node, tree, tree, int, bool *)
485 tree type = TREE_TYPE (*node);
487 if (TREE_CODE (*node) == FUNCTION_DECL)
488 TREE_READONLY (*node) = 1;
489 else if (TREE_CODE (type) == POINTER_TYPE
490 && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
491 TREE_TYPE (*node)
492 = build_pointer_type
493 (build_type_variant (TREE_TYPE (type), 1,
494 TREE_THIS_VOLATILE (TREE_TYPE (type))));
495 else
496 gcc_unreachable ();
498 return NULL_TREE;
501 /* Handle a "malloc" attribute; arguments as in
502 struct attribute_spec.handler. */
504 tree
505 handle_malloc_attribute (tree *node, tree, tree, int, bool *)
507 gcc_assert (TREE_CODE (*node) == FUNCTION_DECL
508 && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node))));
509 DECL_IS_MALLOC (*node) = 1;
510 return NULL_TREE;
513 /* Handle a "pure" attribute; arguments as in
514 struct attribute_spec.handler. */
516 static tree
517 handle_pure_attribute (tree *node, tree, tree, int, bool *)
519 gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
520 DECL_PURE_P (*node) = 1;
521 return NULL_TREE;
524 /* Handle a "no vops" attribute; arguments as in
525 struct attribute_spec.handler. */
527 static tree
528 handle_novops_attribute (tree *node, tree, tree, int, bool *)
530 gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
531 DECL_IS_NOVOPS (*node) = 1;
532 return NULL_TREE;
535 /* Helper for nonnull attribute handling; fetch the operand number
536 from the attribute argument list. */
538 static bool
539 get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp)
541 /* Verify the arg number is a constant. */
542 if (!tree_fits_uhwi_p (arg_num_expr))
543 return false;
545 *valp = TREE_INT_CST_LOW (arg_num_expr);
546 return true;
549 /* Handle the "nonnull" attribute. */
551 static tree
552 handle_nonnull_attribute (tree *node, tree, tree args, int, bool *)
554 tree type = *node;
556 /* If no arguments are specified, all pointer arguments should be
557 non-null. Verify a full prototype is given so that the arguments
558 will have the correct types when we actually check them later.
559 Avoid diagnosing type-generic built-ins since those have no
560 prototype. */
561 if (!args)
563 gcc_assert (prototype_p (type)
564 || !TYPE_ATTRIBUTES (type)
565 || lookup_attribute ("type generic", TYPE_ATTRIBUTES (type)));
567 return NULL_TREE;
570 /* Argument list specified. Verify that each argument number references
571 a pointer argument. */
572 for (; args; args = TREE_CHAIN (args))
574 tree argument;
575 unsigned HOST_WIDE_INT arg_num = 0, ck_num;
577 if (!get_nonnull_operand (TREE_VALUE (args), &arg_num))
578 gcc_unreachable ();
580 argument = TYPE_ARG_TYPES (type);
581 if (argument)
583 for (ck_num = 1; ; ck_num++)
585 if (!argument || ck_num == arg_num)
586 break;
587 argument = TREE_CHAIN (argument);
590 gcc_assert (argument
591 && TREE_CODE (TREE_VALUE (argument)) == POINTER_TYPE);
595 return NULL_TREE;
598 /* Handle a "nothrow" attribute; arguments as in
599 struct attribute_spec.handler. */
601 static tree
602 handle_nothrow_attribute (tree *node, tree, tree, int, bool *)
604 gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
605 TREE_NOTHROW (*node) = 1;
606 return NULL_TREE;
609 /* Handle a "type generic" attribute; arguments as in
610 struct attribute_spec.handler. */
612 static tree
613 handle_type_generic_attribute (tree *node, tree, tree, int, bool *)
615 /* Ensure we have a function type. */
616 gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
618 /* Ensure we have a variadic function. */
619 gcc_assert (!prototype_p (*node) || stdarg_p (*node));
621 return NULL_TREE;
624 /* Handle a "transaction_pure" attribute; arguments as in
625 struct attribute_spec.handler. */
627 static tree
628 handle_transaction_pure_attribute (tree *node, tree, tree, int, bool *)
630 /* Ensure we have a function type. */
631 gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
633 return NULL_TREE;
636 /* Handle a "returns_twice" attribute; arguments as in
637 struct attribute_spec.handler. */
639 static tree
640 handle_returns_twice_attribute (tree *node, tree, tree, int, bool *)
642 gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
644 DECL_IS_RETURNS_TWICE (*node) = 1;
646 return NULL_TREE;
649 /* Handle a "fn spec" attribute; arguments as in
650 struct attribute_spec.handler. */
652 tree
653 handle_fnspec_attribute (tree *, tree, tree args, int, bool *)
655 gcc_assert (args
656 && TREE_CODE (TREE_VALUE (args)) == STRING_CST
657 && !TREE_CHAIN (args));
658 return NULL_TREE;
661 /* Language specific attribute handlers.
662 These functions take the arguments:
663 (tree *node, tree name, tree args, int flags, bool *no_add_attrs) */
665 /* Handle a "noinline" attribute; arguments as in
666 struct attribute_spec.handler. */
668 static tree
669 d_handle_noinline_attribute (tree *node, tree name, tree, int,
670 bool *no_add_attrs)
672 if (TREE_CODE (*node) == FUNCTION_DECL)
673 DECL_UNINLINABLE (*node) = 1;
674 else
676 warning (OPT_Wattributes, "%qE attribute ignored", name);
677 *no_add_attrs = true;
680 return NULL_TREE;
683 /* Handle a "always_inline" attribute; arguments as in
684 struct attribute_spec.handler. */
686 static tree
687 d_handle_always_inline_attribute (tree *node, tree name, tree, int,
688 bool *no_add_attrs)
690 if (TREE_CODE (*node) == FUNCTION_DECL)
692 DECL_DECLARED_INLINE_P (*node) = 1;
693 DECL_DISREGARD_INLINE_LIMITS (*node) = 1;
695 else
697 warning (OPT_Wattributes, "%qE attribute ignored", name);
698 *no_add_attrs = true;
701 return NULL_TREE;
704 /* Handle a "flatten" attribute; arguments as in
705 struct attribute_spec.handler. */
707 static tree
708 d_handle_flatten_attribute (tree *node, tree name, tree, int,
709 bool *no_add_attrs)
711 if (TREE_CODE (*node) != FUNCTION_DECL)
713 warning (OPT_Wattributes, "%qE attribute ignored", name);
714 *no_add_attrs = true;
717 return NULL_TREE;
720 /* Handle a "target" attribute; arguments as in
721 struct attribute_spec.handler. */
723 static tree
724 d_handle_target_attribute (tree *node, tree name, tree args, int flags,
725 bool *no_add_attrs)
727 /* Ensure we have a function type. */
728 if (TREE_CODE (*node) != FUNCTION_DECL)
730 warning (OPT_Wattributes, "%qE attribute ignored", name);
731 *no_add_attrs = true;
733 else if (!targetm.target_option.valid_attribute_p (*node, name, args, flags))
734 *no_add_attrs = true;
736 /* Check that there's no empty string in values of the attribute. */
737 for (tree t = args; t != NULL_TREE; t = TREE_CHAIN (t))
739 tree value = TREE_VALUE (t);
740 if (TREE_CODE (value) != STRING_CST
741 || (TREE_STRING_LENGTH (value) != 0
742 && TREE_STRING_POINTER (value)[0] != '\0'))
743 continue;
745 warning (OPT_Wattributes, "empty string in attribute %<target%>");
746 *no_add_attrs = true;
749 return NULL_TREE;
752 /* Handle a "target_clones" attribute; arguments as in
753 struct attribute_spec.handler. */
755 static tree
756 d_handle_target_clones_attribute (tree *node, tree name, tree, int,
757 bool *no_add_attrs)
759 /* Ensure we have a function type. */
760 if (TREE_CODE (*node) != FUNCTION_DECL)
762 warning (OPT_Wattributes, "%qE attribute ignored", name);
763 *no_add_attrs = true;
765 else
767 /* Do not inline functions with multiple clone targets. */
768 DECL_UNINLINABLE (*node) = 1;
771 return NULL_TREE;
774 /* Arguments being collected for optimization. */
775 static GTY(()) vec <const char *, va_gc> *optimize_args;
777 /* Inner function to convert a TREE_LIST to argv string to parse the optimize
778 options in ARGS. */
780 static bool
781 parse_optimize_options (tree args)
783 bool ret = true;
785 /* Build up argv vector. Just in case the string is stored away, use garbage
786 collected strings. */
787 vec_safe_truncate (optimize_args, 0);
788 vec_safe_push (optimize_args, (const char *) NULL);
790 for (tree ap = args; ap != NULL_TREE; ap = TREE_CHAIN (ap))
792 tree value = TREE_VALUE (ap);
794 if (TREE_CODE (value) == INTEGER_CST)
796 char buffer[20];
797 sprintf (buffer, "-O%ld", (long) TREE_INT_CST_LOW (value));
798 vec_safe_push (optimize_args, ggc_strdup (buffer));
800 else if (TREE_CODE (value) == STRING_CST)
802 size_t len = TREE_STRING_LENGTH (value);
803 const char *p = TREE_STRING_POINTER (value);
805 /* If the user supplied -Oxxx or -fxxx, only allow -Oxxx or -fxxx
806 options. */
807 if (*p == '-' && p[1] != 'O' && p[1] != 'f')
809 ret = false;
810 warning (OPT_Wattributes,
811 "bad option %qs to attribute %<optimize%>", p);
812 continue;
815 /* Can't use GC memory here. */
816 char *q = XOBNEWVEC (&opts_obstack, char, len + 3);
817 char *r = q;
819 if (*p != '-')
821 *r++ = '-';
823 /* Assume that Ox is -Ox, a numeric value is -Ox, a s by
824 itself is -Os, and any other switch begins with a -f. */
825 if ((*p >= '0' && *p <= '9') || (p[0] == 's' && p[1] == '\0'))
826 *r++ = 'O';
827 else if (*p != 'O')
828 *r++ = 'f';
831 memcpy (r, p, len);
832 r[len] = '\0';
833 vec_safe_push (optimize_args, (const char *) q);
837 unsigned opt_argc = optimize_args->length ();
838 const char **opt_argv
839 = (const char **) alloca (sizeof (char *) * (opt_argc + 1));
841 for (unsigned i = 1; i < opt_argc; i++)
842 opt_argv[i] = (*optimize_args)[i];
844 /* Now parse the options. */
845 struct cl_decoded_option *decoded_options;
846 unsigned int decoded_options_count;
848 decode_cmdline_options_to_array_default_mask (opt_argc, opt_argv,
849 &decoded_options,
850 &decoded_options_count);
851 /* Drop non-Optimization options. */
852 unsigned j = 1;
853 for (unsigned i = 1; i < decoded_options_count; ++i)
855 unsigned opt_index = decoded_options[i].opt_index;
856 if (opt_index >= cl_options_count
857 || ! (cl_options[opt_index].flags & CL_OPTIMIZATION))
859 ret = false;
860 warning (OPT_Wattributes,
861 "bad option %qs to attribute %<optimize%>",
862 decoded_options[i].orig_option_with_args_text);
863 continue;
865 if (i != j)
866 decoded_options[j] = decoded_options[i];
867 j++;
869 decoded_options_count = j;
870 /* And apply them. */
871 decode_options (&global_options, &global_options_set,
872 decoded_options, decoded_options_count,
873 input_location, global_dc, NULL);
875 targetm.override_options_after_change();
877 optimize_args->truncate (0);
878 return ret;
881 /* Handle a "optimize" attribute; arguments as in
882 struct attribute_spec.handler. */
884 static tree
885 d_handle_optimize_attribute (tree *node, tree name, tree args, int,
886 bool *no_add_attrs)
888 /* Ensure we have a function type. */
889 if (TREE_CODE (*node) != FUNCTION_DECL)
891 warning (OPT_Wattributes, "%qE attribute ignored", name);
892 *no_add_attrs = true;
894 else
896 struct cl_optimization cur_opts;
897 tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node);
899 /* Save current options. */
900 cl_optimization_save (&cur_opts, &global_options, &global_options_set);
901 tree prev_target_node = build_target_option_node (&global_options,
902 &global_options_set);
904 /* If we previously had some optimization options, use them as the
905 default. */
906 gcc_options *saved_global_options = NULL;
907 if (flag_checking)
909 saved_global_options = XNEW (gcc_options);
910 *saved_global_options = global_options;
913 if (old_opts)
914 cl_optimization_restore (&global_options, &global_options_set,
915 TREE_OPTIMIZATION (old_opts));
917 /* Parse options, and update the vector. */
918 parse_optimize_options (args);
919 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)
920 = build_optimization_node (&global_options, &global_options_set);
921 tree target_node = build_target_option_node (&global_options,
922 &global_options_set);
923 if (prev_target_node != target_node)
924 DECL_FUNCTION_SPECIFIC_TARGET (*node) = target_node;
926 /* Restore current options. */
927 cl_optimization_restore (&global_options, &global_options_set,
928 &cur_opts);
929 cl_target_option_restore (&global_options, &global_options_set,
930 TREE_TARGET_OPTION (prev_target_node));
931 if (saved_global_options != NULL)
933 cl_optimization_compare (saved_global_options, &global_options);
934 free (saved_global_options);
938 return NULL_TREE;
941 /* Handle a "noclone" attribute; arguments as in
942 struct attribute_spec.handler. */
944 static tree
945 d_handle_noclone_attribute (tree *node, tree name, tree, int,
946 bool *no_add_attrs)
948 if (TREE_CODE (*node) != FUNCTION_DECL)
950 warning (OPT_Wattributes, "%qE attribute ignored", name);
951 *no_add_attrs = true;
954 return NULL_TREE;
957 /* Handle a "no_icf" attribute; arguments as in
958 struct attribute_spec.handler. */
960 static tree
961 d_handle_noicf_attribute (tree *node, tree name, tree, int,
962 bool *no_add_attrs)
964 if (TREE_CODE (*node) != FUNCTION_DECL)
966 warning (OPT_Wattributes, "%qE attribute ignored", name);
967 *no_add_attrs = true;
970 return NULL_TREE;
973 /* Handle a "noipa" attribute; arguments as in
974 struct attribute_spec.handler. */
976 static tree
977 d_handle_noipa_attribute (tree *node, tree name, tree, int,
978 bool *no_add_attrs)
980 if (TREE_CODE (*node) != FUNCTION_DECL)
982 warning (OPT_Wattributes, "%qE attribute ignored", name);
983 *no_add_attrs = true;
986 return NULL_TREE;
989 /* Handle a "section" attribute; arguments as in
990 struct attribute_spec.handler. */
992 static tree
993 d_handle_section_attribute (tree *node, tree name, tree args, int flags,
994 bool *no_add_attrs)
996 if (!targetm_common.have_named_sections)
998 error ("section attributes are not supported for this target");
999 *no_add_attrs = true;
1000 return NULL_TREE;
1003 if (!VAR_OR_FUNCTION_DECL_P (*node))
1005 error ("section attribute not allowed for %q+D", *node);
1006 *no_add_attrs = true;
1007 return NULL_TREE;
1010 if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
1012 error ("section attribute argument not a string constant");
1013 *no_add_attrs = true;
1014 return NULL_TREE;
1017 if (VAR_P (*node)
1018 && current_function_decl != NULL_TREE
1019 && !TREE_STATIC (*node))
1021 error ("section attribute cannot be specified for local variables");
1022 *no_add_attrs = true;
1023 return NULL_TREE;
1026 /* The decl may have already been given a section attribute
1027 from a previous declaration. Ensure they match. */
1028 if (DECL_SECTION_NAME (*node) != NULL
1029 && strcmp (DECL_SECTION_NAME (*node),
1030 TREE_STRING_POINTER (TREE_VALUE (args))) != 0)
1032 error ("section of %q+D conflicts with previous declaration", *node);
1033 *no_add_attrs = true;
1034 return NULL_TREE;
1037 if (VAR_P (*node)
1038 && !targetm.have_tls && targetm.emutls.tmpl_section
1039 && DECL_THREAD_LOCAL_P (*node))
1041 error ("section of %q+D cannot be overridden", *node);
1042 *no_add_attrs = true;
1043 return NULL_TREE;
1046 tree res = targetm.handle_generic_attribute (node, name, args, flags,
1047 no_add_attrs);
1049 /* If the back end confirms the attribute can be added then continue onto
1050 final processing. */
1051 if (*no_add_attrs)
1052 return NULL_TREE;
1054 set_decl_section_name (*node, TREE_STRING_POINTER (TREE_VALUE (args)));
1055 return res;
1058 /* Handle a "symver" and attribute; arguments as in
1059 struct attribute_spec.handler. */
1061 static tree
1062 d_handle_symver_attribute (tree *node, tree, tree args, int, bool *no_add_attrs)
1064 if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL)
1066 warning (OPT_Wattributes,
1067 "%<symver%> attribute only applies to functions and variables");
1068 *no_add_attrs = true;
1069 return NULL_TREE;
1072 if (!decl_in_symtab_p (*node))
1074 warning (OPT_Wattributes,
1075 "%<symver%> attribute is only applicable to symbols");
1076 *no_add_attrs = true;
1077 return NULL_TREE;
1080 for (; args; args = TREE_CHAIN (args))
1082 tree symver = TREE_VALUE (args);
1083 if (TREE_CODE (symver) != STRING_CST)
1085 error ("%<symver%> attribute argument not a string constant");
1086 *no_add_attrs = true;
1087 return NULL_TREE;
1090 const char *symver_str = TREE_STRING_POINTER (symver);
1092 int ats = 0;
1093 for (int n = 0; (int)n < TREE_STRING_LENGTH (symver); n++)
1094 if (symver_str[n] == '@')
1095 ats++;
1097 if (ats != 1 && ats != 2)
1099 error ("symver attribute argument must have format %<name@nodename%>");
1100 error ("%<symver%> attribute argument %qs must contain one or two "
1101 "%<@%>", symver_str);
1102 *no_add_attrs = true;
1103 return NULL_TREE;
1107 return NULL_TREE;
1110 /* Handle a "weak" attribute; arguments as in
1111 struct attribute_spec.handler. */
1113 static tree
1114 d_handle_weak_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
1116 if (TREE_CODE (*node) == FUNCTION_DECL
1117 && DECL_DECLARED_INLINE_P (*node))
1119 warning (OPT_Wattributes, "inline function %q+D declared weak", *node);
1120 *no_add_attrs = true;
1122 else if (VAR_OR_FUNCTION_DECL_P (*node))
1124 struct symtab_node *n = symtab_node::get (*node);
1125 if (n && n->refuse_visibility_changes)
1126 error ("%q+D declared weak after being used", *node);
1127 declare_weak (*node);
1129 else
1130 warning (OPT_Wattributes, "%qE attribute ignored", name);
1132 return NULL_TREE;
1135 /* Handle a "noplt" attribute; arguments as in
1136 struct attribute_spec.handler. */
1138 static tree
1139 d_handle_noplt_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
1141 if (TREE_CODE (*node) != FUNCTION_DECL)
1143 warning (OPT_Wattributes, "%qE attribute ignored", name);
1144 *no_add_attrs = true;
1147 return NULL_TREE;
1150 /* Verify that argument value POS at position ARGNO to attribute ATNAME applied
1151 to function FNTYPE refers to a function parameter at position POS and is a
1152 valid integer type. When ZERO_BASED is true, POS is adjusted to be 1-based.
1153 If successful, POS is returned. Otherwise, issue appropriate warnings and
1154 return null. A non-zero 1-based ARGNO should be passed in by callers only
1155 for attributes with more than one argument. */
1157 static tree
1158 positional_argument (const_tree fntype, const_tree atname, tree pos,
1159 int argno, bool zero_based)
1161 tree postype = TREE_TYPE (pos);
1163 if (pos == error_mark_node || !postype)
1165 /* Only mention the positional argument number when it's non-zero. */
1166 if (argno < 1)
1167 warning (OPT_Wattributes,
1168 "%qE attribute argument is invalid", atname);
1169 else
1170 warning (OPT_Wattributes,
1171 "%qE attribute argument %i is invalid", atname, argno);
1173 return NULL_TREE;
1176 if (!INTEGRAL_TYPE_P (postype))
1178 /* Handle this case specially to avoid mentioning the value
1179 of pointer constants in diagnostics. Only mention
1180 the positional argument number when it's non-zero. */
1181 if (argno < 1)
1182 warning (OPT_Wattributes,
1183 "%qE attribute argument has type %qT",
1184 atname, postype);
1185 else
1186 warning (OPT_Wattributes,
1187 "%qE attribute argument %i has type %qT",
1188 atname, argno, postype);
1190 return NULL_TREE;
1193 if (TREE_CODE (pos) != INTEGER_CST)
1195 /* Only mention the argument number when it's non-zero. */
1196 if (argno < 1)
1197 warning (OPT_Wattributes,
1198 "%qE attribute argument value %qE is not an integer "
1199 "constant",
1200 atname, pos);
1201 else
1202 warning (OPT_Wattributes,
1203 "%qE attribute argument %i value %qE is not an integer "
1204 "constant",
1205 atname, argno, pos);
1207 return NULL_TREE;
1210 /* Validate the value of the position argument. If 0-based, then it should
1211 not be negative. If 1-based, it should be greater than zero. */
1212 if ((zero_based && tree_int_cst_sgn (pos) < 0)
1213 || (!zero_based && tree_int_cst_sgn (pos) < 1))
1215 if (argno < 1)
1216 warning (OPT_Wattributes,
1217 "%qE attribute argument value %qE does not refer to "
1218 "a function parameter",
1219 atname, pos);
1220 else
1221 warning (OPT_Wattributes,
1222 "%qE attribute argument %i value %qE does not refer to "
1223 "a function parameter",
1224 atname, argno, pos);
1226 return NULL_TREE;
1229 /* Adjust the value of pos to be 1-based. */
1230 tree adjusted_pos = (zero_based)
1231 ? int_const_binop (PLUS_EXPR, pos, integer_one_node) : pos;
1233 if (!prototype_p (fntype))
1234 return adjusted_pos;
1236 /* Verify that the argument position does not exceed the number
1237 of formal arguments to the function. */
1238 unsigned nargs = type_num_arguments (fntype);
1239 if (!nargs
1240 || !tree_fits_uhwi_p (adjusted_pos)
1241 || !IN_RANGE (tree_to_uhwi (adjusted_pos), 1, nargs))
1243 if (argno < 1)
1244 warning (OPT_Wattributes,
1245 "%qE attribute argument value %qE exceeds the number "
1246 "of function parameters %u",
1247 atname, pos, nargs);
1248 else
1249 warning (OPT_Wattributes,
1250 "%qE attribute argument %i value %qE exceeds the number "
1251 "of function parameters %u",
1252 atname, argno, pos, nargs);
1254 return NULL_TREE;
1257 /* Verify that the type of the referenced formal argument matches
1258 the expected type. */
1259 unsigned HOST_WIDE_INT ipos = tree_to_uhwi (adjusted_pos);
1261 /* Zero was handled above. */
1262 gcc_assert (ipos != 0);
1264 if (tree argtype = type_argument_type (fntype, ipos))
1266 /* Accept types that match INTEGRAL_TYPE_P except for bool. */
1267 if (!INTEGRAL_TYPE_P (argtype) || TREE_CODE (argtype) == BOOLEAN_TYPE)
1269 if (argno < 1)
1270 warning (OPT_Wattributes,
1271 "%qE attribute argument value %qE refers to "
1272 "parameter type %qT",
1273 atname, pos, argtype);
1274 else
1275 warning (OPT_Wattributes,
1276 "%qE attribute argument %i value %qE refers to "
1277 "parameter type %qT",
1278 atname, argno, pos, argtype);
1280 return NULL_TREE;
1283 return adjusted_pos;
1286 /* Argument position exceeding number of parameters was handled above. */
1287 gcc_unreachable ();
1290 /* Handle a "alloc_size" attribute; arguments as in
1291 struct attribute_spec.handler. */
1293 static tree
1294 d_handle_alloc_size_attribute (tree *node, tree name, tree args, int,
1295 bool *no_add_attrs)
1297 tree fntype = *node;
1298 tree rettype = TREE_TYPE (fntype);
1299 if (!POINTER_TYPE_P (rettype))
1301 warning (OPT_Wattributes,
1302 "%qE attribute ignored on a function returning %qT",
1303 name, rettype);
1304 *no_add_attrs = true;
1305 return NULL_TREE;
1308 /* The first argument SIZE_ARG is never null. */
1309 tree size_arg = TREE_VALUE (args);
1310 tree next = TREE_CHAIN (args);
1312 /* NUM_ARG is null when the attribute includes just one argument, or is
1313 explictly set to null if it has been left uninitialized by the caller. */
1314 tree num_arg = NULL_TREE;
1315 if (next != NULL_TREE)
1317 if (TREE_VALUE (next) != TYPE_MIN_VALUE (d_int_type))
1318 num_arg = TREE_VALUE (next);
1320 next = TREE_CHAIN (next);
1323 /* If ZERO_ARG is set and true, arguments positions are treated as 0-based.
1324 Otherwise the default is 1-based. */
1325 bool zero_based = false;
1326 if (next != NULL_TREE)
1327 zero_based = integer_truep (TREE_VALUE (next));
1329 /* Update the argument values with the real argument position. */
1330 if (tree val = positional_argument (fntype, name, size_arg, num_arg ? 1 : 0,
1331 zero_based))
1332 TREE_VALUE (args) = val;
1333 else
1334 *no_add_attrs = true;
1336 if (num_arg != NULL_TREE)
1338 args = TREE_CHAIN (args);
1339 if (tree val = positional_argument (fntype, name, num_arg, 2, zero_based))
1340 TREE_VALUE (args) = val;
1341 else
1342 *no_add_attrs = true;
1345 /* Terminate the original TREE_CHAIN in `args' to remove any remaining
1346 D-specific `alloc_size` arguments. */
1347 TREE_CHAIN (args) = NULL_TREE;
1349 return NULL_TREE;
1352 /* Handle a "cold" and attribute; arguments as in
1353 struct attribute_spec.handler. */
1355 static tree
1356 d_handle_cold_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
1358 if (TREE_CODE (*node) != FUNCTION_DECL)
1360 warning (OPT_Wattributes, "%qE attribute ignored", name);
1361 *no_add_attrs = true;
1364 return NULL_TREE;
1367 /* Handle a "restrict" attribute; arguments as in
1368 struct attribute_spec.handler. */
1370 static tree
1371 d_handle_restrict_attribute (tree *node, tree name, tree, int,
1372 bool *no_add_attrs)
1374 if (TREE_CODE (*node) == PARM_DECL && POINTER_TYPE_P (TREE_TYPE (*node)))
1376 TREE_TYPE (*node) = build_qualified_type (TREE_TYPE (*node),
1377 TYPE_QUAL_RESTRICT);
1379 else
1381 warning (OPT_Wattributes, "%qE attribute ignored", name);
1382 *no_add_attrs = true;
1385 return NULL_TREE;
1388 /* Handle a "used" attribute; arguments as in
1389 struct attribute_spec.handler. */
1391 static tree
1392 d_handle_used_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
1394 if (TREE_CODE (*node) == FUNCTION_DECL
1395 || (VAR_P (*node) && TREE_STATIC (*node))
1396 || (TREE_CODE (*node) == TYPE_DECL))
1398 TREE_USED (*node) = 1;
1399 DECL_PRESERVE_P (*node) = 1;
1400 if (VAR_P (*node))
1401 DECL_READ_P (*node) = 1;
1403 else
1405 warning (OPT_Wattributes, "%qE attribute ignored", name);
1406 *no_add_attrs = true;
1409 return NULL_TREE;
1412 /* Handle an "visibility" attribute; arguments as in
1413 struct attribute_spec.handler. */
1415 static tree
1416 d_handle_visibility_attribute (tree *node, tree name, tree args,
1417 int, bool *)
1419 /* If this is a type, set the visibility on the type decl. */
1420 tree decl = *node;
1421 if (TYPE_P (decl))
1423 decl = TYPE_NAME (decl);
1424 if (decl == NULL_TREE || TREE_CODE (decl) != TYPE_DECL)
1426 warning (OPT_Wattributes, "%qE attribute ignored on types", name);
1427 return NULL_TREE;
1431 if (decl_function_context (decl) != 0 || !TREE_PUBLIC (decl))
1433 warning (OPT_Wattributes, "%qE attribute ignored", name);
1434 return NULL_TREE;
1437 tree id = TREE_VALUE (args);
1438 if (TREE_CODE (id) != STRING_CST)
1440 error ("visibility argument not a string");
1441 return NULL_TREE;
1444 enum symbol_visibility vis;
1445 if (strcmp (TREE_STRING_POINTER (id), "default") == 0)
1446 vis = VISIBILITY_DEFAULT;
1447 else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0)
1448 vis = VISIBILITY_INTERNAL;
1449 else if (strcmp (TREE_STRING_POINTER (id), "hidden") == 0)
1450 vis = VISIBILITY_HIDDEN;
1451 else if (strcmp (TREE_STRING_POINTER (id), "protected") == 0)
1452 vis = VISIBILITY_PROTECTED;
1453 else
1455 error ("attribute %qE argument must be one of %qs, %qs, %qs, or %qs",
1456 name, "default", "hidden", "protected", "internal");
1457 vis = VISIBILITY_DEFAULT;
1460 if (DECL_VISIBILITY_SPECIFIED (decl) && vis != DECL_VISIBILITY (decl))
1462 tree attributes = (TYPE_P (*node)
1463 ? TYPE_ATTRIBUTES (*node)
1464 : DECL_ATTRIBUTES (decl));
1465 if (lookup_attribute ("visibility", attributes))
1466 error ("%qD redeclared with different visibility", decl);
1467 else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
1468 && lookup_attribute ("dllimport", attributes))
1469 error ("%qD was declared %qs which implies default visibility",
1470 decl, "export");
1471 else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
1472 && lookup_attribute ("dllexport", attributes))
1473 error ("%qD was declared %qs which implies default visibility",
1474 decl, "export");
1477 DECL_VISIBILITY (decl) = vis;
1478 DECL_VISIBILITY_SPECIFIED (decl) = 1;
1480 /* Go ahead and attach the attribute to the node as well. This is needed
1481 so we can determine whether we have VISIBILITY_DEFAULT because the
1482 visibility was not specified, or because it was explicitly overridden
1483 from the containing scope. */
1485 return NULL_TREE;