1 /* d-attribs.c -- D attributes handling.
2 Copyright (C) 2015-2019 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/declaration.h"
26 #include "dmd/mtype.h"
29 #include "diagnostic.h"
34 #include "common/common-target.h"
35 #include "stringpool.h"
42 /* Internal attribute handlers for built-in functions. */
43 static tree
handle_noreturn_attribute (tree
*, tree
, tree
, int, bool *);
44 static tree
handle_leaf_attribute (tree
*, tree
, tree
, int, bool *);
45 static tree
handle_const_attribute (tree
*, tree
, tree
, int, bool *);
46 static tree
handle_malloc_attribute (tree
*, tree
, tree
, int, bool *);
47 static tree
handle_pure_attribute (tree
*, tree
, tree
, int, bool *);
48 static tree
handle_novops_attribute (tree
*, tree
, tree
, int, bool *);
49 static tree
handle_nonnull_attribute (tree
*, tree
, tree
, int, bool *);
50 static tree
handle_nothrow_attribute (tree
*, tree
, tree
, int, bool *);
51 static tree
handle_type_generic_attribute (tree
*, tree
, tree
, int, bool *);
52 static tree
handle_transaction_pure_attribute (tree
*, tree
, tree
, int, bool *);
53 static tree
handle_returns_twice_attribute (tree
*, tree
, tree
, int, bool *);
54 static tree
handle_fnspec_attribute (tree
*, tree
, tree
, int, bool *);
56 /* D attribute handlers for user defined attributes. */
57 static tree
d_handle_noinline_attribute (tree
*, tree
, tree
, int, bool *);
58 static tree
d_handle_forceinline_attribute (tree
*, tree
, tree
, int, bool *);
59 static tree
d_handle_flatten_attribute (tree
*, tree
, tree
, int, bool *);
60 static tree
d_handle_target_attribute (tree
*, tree
, tree
, int, bool *);
61 static tree
d_handle_noclone_attribute (tree
*, tree
, tree
, int, bool *);
62 static tree
d_handle_section_attribute (tree
*, tree
, tree
, int, bool *);
63 static tree
d_handle_alias_attribute (tree
*, tree
, tree
, int, bool *);
64 static tree
d_handle_weak_attribute (tree
*, tree
, tree
, int, bool *) ;
66 /* Helper to define attribute exclusions. */
67 #define ATTR_EXCL(name, function, type, variable) \
68 { name, function, type, variable }
70 /* Define attributes that are mutually exclusive with one another. */
71 static const struct attribute_spec::exclusions attr_noreturn_exclusions
[] =
73 ATTR_EXCL ("const", true, true, true),
74 ATTR_EXCL ("malloc", true, true, true),
75 ATTR_EXCL ("pure", true, true, true),
76 ATTR_EXCL ("returns_twice", true, true, true),
77 ATTR_EXCL (NULL
, false, false, false),
80 static const struct attribute_spec::exclusions attr_returns_twice_exclusions
[] =
82 ATTR_EXCL ("noreturn", true, true, true),
83 ATTR_EXCL (NULL
, false, false, false),
86 static const struct attribute_spec::exclusions attr_const_pure_exclusions
[] =
88 ATTR_EXCL ("const", true, true, true),
89 ATTR_EXCL ("noreturn", true, true, true),
90 ATTR_EXCL ("pure", true, true, true),
91 ATTR_EXCL (NULL
, false, false, false)
94 static const struct attribute_spec::exclusions attr_inline_exclusions
[] =
96 ATTR_EXCL ("noinline", true, true, true),
97 ATTR_EXCL (NULL
, false, false, false),
100 static const struct attribute_spec::exclusions attr_noinline_exclusions
[] =
102 ATTR_EXCL ("forceinline", true, true, true),
103 ATTR_EXCL (NULL
, false, false, false),
106 /* Helper to define an attribute. */
107 #define ATTR_SPEC(name, min_len, max_len, decl_req, type_req, fn_type_req, \
108 affects_type_identity, handler, exclude) \
109 { name, min_len, max_len, decl_req, type_req, fn_type_req, \
110 affects_type_identity, handler, exclude }
112 /* Table of machine-independent attributes.
113 For internal use (marking of built-ins) only. */
114 const attribute_spec d_langhook_common_attribute_table
[] =
116 ATTR_SPEC ("noreturn", 0, 0, true, false, false, false,
117 handle_noreturn_attribute
, attr_noreturn_exclusions
),
118 ATTR_SPEC ("leaf", 0, 0, true, false, false, false,
119 handle_leaf_attribute
, NULL
),
120 ATTR_SPEC ("const", 0, 0, true, false, false, false,
121 handle_const_attribute
, attr_const_pure_exclusions
),
122 ATTR_SPEC ("malloc", 0, 0, true, false, false, false,
123 handle_malloc_attribute
, NULL
),
124 ATTR_SPEC ("returns_twice", 0, 0, true, false, false, false,
125 handle_returns_twice_attribute
, attr_returns_twice_exclusions
),
126 ATTR_SPEC ("pure", 0, 0, true, false, false, false,
127 handle_pure_attribute
, attr_const_pure_exclusions
),
128 ATTR_SPEC ("nonnull", 0, -1, false, true, true, false,
129 handle_nonnull_attribute
, NULL
),
130 ATTR_SPEC ("nothrow", 0, 0, true, false, false, false,
131 handle_nothrow_attribute
, NULL
),
132 ATTR_SPEC ("transaction_pure", 0, 0, false, true, true, false,
133 handle_transaction_pure_attribute
, NULL
),
134 ATTR_SPEC ("no vops", 0, 0, true, false, false, false,
135 handle_novops_attribute
, NULL
),
136 ATTR_SPEC ("type generic", 0, 0, false, true, true, false,
137 handle_type_generic_attribute
, NULL
),
138 ATTR_SPEC ("fn spec", 1, 1, false, true, true, false,
139 handle_fnspec_attribute
, NULL
),
140 ATTR_SPEC (NULL
, 0, 0, false, false, false, false, NULL
, NULL
),
143 /* Table of D language attributes exposed by `gcc.attribute' UDAs. */
144 const attribute_spec d_langhook_attribute_table
[] =
146 ATTR_SPEC ("noinline", 0, 0, true, false, false, false,
147 d_handle_noinline_attribute
, attr_noinline_exclusions
),
148 ATTR_SPEC ("forceinline", 0, 0, true, false, false, false,
149 d_handle_forceinline_attribute
, attr_inline_exclusions
),
150 ATTR_SPEC ("flatten", 0, 0, true, false, false, false,
151 d_handle_flatten_attribute
, NULL
),
152 ATTR_SPEC ("target", 1, -1, true, false, false, false,
153 d_handle_target_attribute
, NULL
),
154 ATTR_SPEC ("noclone", 0, 0, true, false, false, false,
155 d_handle_noclone_attribute
, NULL
),
156 ATTR_SPEC ("section", 1, 1, true, false, false, false,
157 d_handle_section_attribute
, NULL
),
158 ATTR_SPEC ("alias", 1, 1, true, false, false, false,
159 d_handle_alias_attribute
, NULL
),
160 ATTR_SPEC ("weak", 0, 0, true, false, false, false,
161 d_handle_weak_attribute
, NULL
),
162 ATTR_SPEC (NULL
, 0, 0, false, false, false, false, NULL
, NULL
),
166 /* Insert the type attribute ATTRNAME with value VALUE into TYPE.
167 Returns a new variant of the original type declaration. */
170 insert_type_attribute (tree type
, const char *attrname
, tree value
)
172 tree ident
= get_identifier (attrname
);
175 value
= tree_cons (NULL_TREE
, value
, NULL_TREE
);
177 tree attribs
= merge_attributes (TYPE_ATTRIBUTES (type
),
178 tree_cons (ident
, value
, NULL_TREE
));
180 return build_type_attribute_variant (type
, attribs
);
183 /* Insert the decl attribute ATTRNAME with value VALUE into DECL. */
186 insert_decl_attribute (tree decl
, const char *attrname
, tree value
)
188 tree ident
= get_identifier (attrname
);
191 value
= tree_cons (NULL_TREE
, value
, NULL_TREE
);
193 tree attribs
= merge_attributes (DECL_ATTRIBUTES (decl
),
194 tree_cons (ident
, value
, NULL_TREE
));
196 return build_decl_attribute_variant (decl
, attribs
);
199 /* Returns TRUE if NAME is an attribute recognized as being handled by
200 the `gcc.attribute' module. */
203 uda_attribute_p (const char *name
)
205 tree ident
= get_identifier (name
);
207 /* Search both our language, and target attribute tables.
208 Common and format attributes are kept internal. */
209 for (const attribute_spec
*p
= d_langhook_attribute_table
; p
->name
; p
++)
211 if (get_identifier (p
->name
) == ident
)
215 for (const attribute_spec
*p
= targetm
.attribute_table
; p
->name
; p
++)
217 if (get_identifier (p
->name
) == ident
)
226 User Defined Attributes (UDA) are compile time expressions that can be
227 attached to a declaration. These attributes can then be queried, extracted,
228 and manipulated at compile-time. There is no run-time component to them.
230 Expand and merge all UDAs found in the EATTRS list that are of type
231 `gcc.attribute.Attribute'. This symbol is internally recognized by the
232 compiler and maps them to their equivalent GCC attribute. */
235 build_attributes (Expressions
*eattrs
)
240 expandTuples (eattrs
);
242 tree attribs
= NULL_TREE
;
244 for (size_t i
= 0; i
< eattrs
->dim
; i
++)
246 Expression
*attr
= (*eattrs
)[i
];
247 Dsymbol
*sym
= attr
->type
->toDsymbol (0);
252 /* Attribute symbol must come from the `gcc.attribute' module. */
253 Dsymbol
*mod
= (Dsymbol
*) sym
->getModule ();
254 if (!(strcmp (mod
->toChars (), "attribute") == 0
255 && mod
->parent
!= NULL
256 && strcmp (mod
->parent
->toChars (), "gcc") == 0
257 && !mod
->parent
->parent
))
260 /* Get the result of the attribute if it hasn't already been folded. */
261 if (attr
->op
== TOKcall
)
262 attr
= attr
->ctfeInterpret ();
264 /* Should now have a struct `Attribute("attrib", "value", ...)'
266 gcc_assert (attr
->op
== TOKstructliteral
);
267 Expressions
*elems
= ((StructLiteralExp
*) attr
)->elements
;
268 Expression
*e0
= (*elems
)[0];
270 if (e0
->op
!= TOKstring
)
272 error ("expected string attribute, not %qs", e0
->toChars ());
273 return error_mark_node
;
276 StringExp
*se
= (StringExp
*) e0
;
277 gcc_assert (se
->sz
== 1);
279 /* Empty string attribute, just ignore it. */
283 /* Check if the attribute is recognized and handled.
284 Done here to report the diagnostic at the right location. */
285 const char *name
= (const char *)(se
->len
? se
->string
: "");
286 if (!uda_attribute_p (name
))
288 warning_at (make_location_t (e0
->loc
), OPT_Wattributes
,
289 "unknown attribute %qs", name
);
290 return error_mark_node
;
293 /* Chain all attribute arguments together. */
294 tree args
= NULL_TREE
;
296 for (size_t j
= 1; j
< elems
->dim
; j
++)
298 Expression
*e
= (*elems
)[j
];
300 if (e
->op
== TOKstring
&& ((StringExp
*) e
)->sz
== 1)
302 StringExp
*s
= (StringExp
*) e
;
303 const char *string
= (const char *)(s
->len
? s
->string
: "");
304 t
= build_string (s
->len
, string
);
309 args
= chainon (args
, build_tree_list (0, t
));
312 tree list
= build_tree_list (get_identifier (name
), args
);
313 attribs
= chainon (attribs
, list
);
319 /* Built-in attribute handlers. */
321 /* Handle a "noreturn" attribute; arguments as in
322 struct attribute_spec.handler. */
325 handle_noreturn_attribute (tree
*node
, tree
ARG_UNUSED (name
),
326 tree
ARG_UNUSED (args
), int ARG_UNUSED (flags
),
327 bool * ARG_UNUSED (no_add_attrs
))
329 tree type
= TREE_TYPE (*node
);
331 if (TREE_CODE (*node
) == FUNCTION_DECL
)
332 TREE_THIS_VOLATILE (*node
) = 1;
333 else if (TREE_CODE (type
) == POINTER_TYPE
334 && TREE_CODE (TREE_TYPE (type
)) == FUNCTION_TYPE
)
337 (build_type_variant (TREE_TYPE (type
),
338 TYPE_READONLY (TREE_TYPE (type
)), 1));
345 /* Handle a "leaf" attribute; arguments as in
346 struct attribute_spec.handler. */
349 handle_leaf_attribute (tree
*node
, tree name
,
350 tree
ARG_UNUSED (args
),
351 int ARG_UNUSED (flags
), bool *no_add_attrs
)
353 if (TREE_CODE (*node
) != FUNCTION_DECL
)
355 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
356 *no_add_attrs
= true;
358 if (!TREE_PUBLIC (*node
))
360 warning (OPT_Wattributes
, "%qE attribute has no effect", name
);
361 *no_add_attrs
= true;
367 /* Handle a "const" attribute; arguments as in
368 struct attribute_spec.handler. */
371 handle_const_attribute (tree
*node
, tree
ARG_UNUSED (name
),
372 tree
ARG_UNUSED (args
), int ARG_UNUSED (flags
),
373 bool * ARG_UNUSED (no_add_attrs
))
375 tree type
= TREE_TYPE (*node
);
377 if (TREE_CODE (*node
) == FUNCTION_DECL
)
378 TREE_READONLY (*node
) = 1;
379 else if (TREE_CODE (type
) == POINTER_TYPE
380 && TREE_CODE (TREE_TYPE (type
)) == FUNCTION_TYPE
)
383 (build_type_variant (TREE_TYPE (type
), 1,
384 TREE_THIS_VOLATILE (TREE_TYPE (type
))));
391 /* Handle a "malloc" attribute; arguments as in
392 struct attribute_spec.handler. */
395 handle_malloc_attribute (tree
*node
, tree
ARG_UNUSED (name
),
396 tree
ARG_UNUSED (args
), int ARG_UNUSED (flags
),
397 bool * ARG_UNUSED (no_add_attrs
))
399 gcc_assert (TREE_CODE (*node
) == FUNCTION_DECL
400 && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node
))));
401 DECL_IS_MALLOC (*node
) = 1;
405 /* Handle a "pure" attribute; arguments as in
406 struct attribute_spec.handler. */
409 handle_pure_attribute (tree
*node
, tree
ARG_UNUSED (name
),
410 tree
ARG_UNUSED (args
), int ARG_UNUSED (flags
),
411 bool * ARG_UNUSED (no_add_attrs
))
413 gcc_assert (TREE_CODE (*node
) == FUNCTION_DECL
);
414 DECL_PURE_P (*node
) = 1;
418 /* Handle a "no vops" attribute; arguments as in
419 struct attribute_spec.handler. */
422 handle_novops_attribute (tree
*node
, tree
ARG_UNUSED (name
),
423 tree
ARG_UNUSED (args
), int ARG_UNUSED (flags
),
424 bool * ARG_UNUSED (no_add_attrs
))
426 gcc_assert (TREE_CODE (*node
) == FUNCTION_DECL
);
427 DECL_IS_NOVOPS (*node
) = 1;
431 /* Helper for nonnull attribute handling; fetch the operand number
432 from the attribute argument list. */
435 get_nonnull_operand (tree arg_num_expr
, unsigned HOST_WIDE_INT
*valp
)
437 /* Verify the arg number is a constant. */
438 if (!tree_fits_uhwi_p (arg_num_expr
))
441 *valp
= TREE_INT_CST_LOW (arg_num_expr
);
445 /* Handle the "nonnull" attribute. */
448 handle_nonnull_attribute (tree
*node
, tree
ARG_UNUSED (name
),
449 tree args
, int ARG_UNUSED (flags
),
450 bool * ARG_UNUSED (no_add_attrs
))
454 /* If no arguments are specified, all pointer arguments should be
455 non-null. Verify a full prototype is given so that the arguments
456 will have the correct types when we actually check them later.
457 Avoid diagnosing type-generic built-ins since those have no
461 gcc_assert (prototype_p (type
)
462 || !TYPE_ATTRIBUTES (type
)
463 || lookup_attribute ("type generic", TYPE_ATTRIBUTES (type
)));
468 /* Argument list specified. Verify that each argument number references
469 a pointer argument. */
470 for (; args
; args
= TREE_CHAIN (args
))
473 unsigned HOST_WIDE_INT arg_num
= 0, ck_num
;
475 if (!get_nonnull_operand (TREE_VALUE (args
), &arg_num
))
478 argument
= TYPE_ARG_TYPES (type
);
481 for (ck_num
= 1; ; ck_num
++)
483 if (!argument
|| ck_num
== arg_num
)
485 argument
= TREE_CHAIN (argument
);
489 && TREE_CODE (TREE_VALUE (argument
)) == POINTER_TYPE
);
496 /* Handle a "nothrow" attribute; arguments as in
497 struct attribute_spec.handler. */
500 handle_nothrow_attribute (tree
*node
, tree
ARG_UNUSED (name
),
501 tree
ARG_UNUSED (args
), int ARG_UNUSED (flags
),
502 bool * ARG_UNUSED (no_add_attrs
))
504 gcc_assert (TREE_CODE (*node
) == FUNCTION_DECL
);
505 TREE_NOTHROW (*node
) = 1;
509 /* Handle a "type_generic" attribute. */
512 handle_type_generic_attribute (tree
*node
, tree
ARG_UNUSED (name
),
513 tree
ARG_UNUSED (args
), int ARG_UNUSED (flags
),
514 bool * ARG_UNUSED (no_add_attrs
))
516 /* Ensure we have a function type. */
517 gcc_assert (TREE_CODE (*node
) == FUNCTION_TYPE
);
519 /* Ensure we have a variadic function. */
520 gcc_assert (!prototype_p (*node
) || stdarg_p (*node
));
525 /* Handle a "transaction_pure" attribute. */
528 handle_transaction_pure_attribute (tree
*node
, tree
ARG_UNUSED (name
),
529 tree
ARG_UNUSED (args
),
530 int ARG_UNUSED (flags
),
531 bool * ARG_UNUSED (no_add_attrs
))
533 /* Ensure we have a function type. */
534 gcc_assert (TREE_CODE (*node
) == FUNCTION_TYPE
);
539 /* Handle a "returns_twice" attribute. */
542 handle_returns_twice_attribute (tree
*node
, tree
ARG_UNUSED (name
),
543 tree
ARG_UNUSED (args
),
544 int ARG_UNUSED (flags
),
545 bool * ARG_UNUSED (no_add_attrs
))
547 gcc_assert (TREE_CODE (*node
) == FUNCTION_DECL
);
549 DECL_IS_RETURNS_TWICE (*node
) = 1;
554 /* Handle a "fn spec" attribute; arguments as in
555 struct attribute_spec.handler. */
558 handle_fnspec_attribute (tree
*node ATTRIBUTE_UNUSED
, tree
ARG_UNUSED (name
),
559 tree args
, int ARG_UNUSED (flags
),
560 bool *no_add_attrs ATTRIBUTE_UNUSED
)
563 && TREE_CODE (TREE_VALUE (args
)) == STRING_CST
564 && !TREE_CHAIN (args
));
568 /* Language specific attribute handlers. */
570 /* Handle a "noinline" attribute. */
573 d_handle_noinline_attribute (tree
*node
, tree name
,
574 tree
ARG_UNUSED (args
),
575 int ARG_UNUSED (flags
), bool *no_add_attrs
)
577 Type
*t
= TYPE_LANG_FRONTEND (TREE_TYPE (*node
));
579 if (t
->ty
== Tfunction
)
580 DECL_UNINLINABLE (*node
) = 1;
583 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
584 *no_add_attrs
= true;
590 /* Handle a "forceinline" attribute. */
593 d_handle_forceinline_attribute (tree
*node
, tree name
,
594 tree
ARG_UNUSED (args
),
595 int ARG_UNUSED (flags
),
598 Type
*t
= TYPE_LANG_FRONTEND (TREE_TYPE (*node
));
600 if (t
->ty
== Tfunction
)
602 tree attributes
= DECL_ATTRIBUTES (*node
);
604 /* Push attribute always_inline. */
605 if (! lookup_attribute ("always_inline", attributes
))
606 DECL_ATTRIBUTES (*node
) = tree_cons (get_identifier ("always_inline"),
607 NULL_TREE
, attributes
);
609 DECL_DECLARED_INLINE_P (*node
) = 1;
610 DECL_NO_INLINE_WARNING_P (*node
) = 1;
611 DECL_DISREGARD_INLINE_LIMITS (*node
) = 1;
615 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
616 *no_add_attrs
= true;
622 /* Handle a "flatten" attribute. */
625 d_handle_flatten_attribute (tree
*node
, tree name
,
626 tree args ATTRIBUTE_UNUSED
,
627 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
629 Type
*t
= TYPE_LANG_FRONTEND (TREE_TYPE (*node
));
631 if (t
->ty
!= Tfunction
)
633 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
634 *no_add_attrs
= true;
640 /* Handle a "target" attribute. */
643 d_handle_target_attribute (tree
*node
, tree name
, tree args
, int flags
,
646 Type
*t
= TYPE_LANG_FRONTEND (TREE_TYPE (*node
));
648 /* Ensure we have a function type. */
649 if (t
->ty
!= Tfunction
)
651 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
652 *no_add_attrs
= true;
654 else if (! targetm
.target_option
.valid_attribute_p (*node
, name
, args
, flags
))
655 *no_add_attrs
= true;
660 /* Handle a "noclone" attribute. */
663 d_handle_noclone_attribute (tree
*node
, tree name
,
664 tree
ARG_UNUSED (args
),
665 int ARG_UNUSED (flags
),
668 Type
*t
= TYPE_LANG_FRONTEND (TREE_TYPE (*node
));
670 if (t
->ty
== Tfunction
)
672 tree attributes
= DECL_ATTRIBUTES (*node
);
674 /* Push attribute noclone. */
675 if (! lookup_attribute ("noclone", attributes
))
676 DECL_ATTRIBUTES (*node
) = tree_cons (get_identifier ("noclone"),
677 NULL_TREE
, attributes
);
681 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
682 *no_add_attrs
= true;
688 /* Handle a "section" attribute; arguments as in
689 struct attribute_spec.handler. */
692 d_handle_section_attribute (tree
*node
, tree
ARG_UNUSED (name
), tree args
,
693 int ARG_UNUSED (flags
), bool *no_add_attrs
)
697 if (targetm_common
.have_named_sections
)
699 if (VAR_OR_FUNCTION_DECL_P (decl
)
700 && TREE_CODE (TREE_VALUE (args
)) == STRING_CST
)
703 && current_function_decl
!= NULL_TREE
704 && !TREE_STATIC (decl
))
706 error_at (DECL_SOURCE_LOCATION (decl
),
707 "section attribute cannot be specified for "
709 *no_add_attrs
= true;
712 /* The decl may have already been given a section attribute
713 from a previous declaration. Ensure they match. */
714 else if (DECL_SECTION_NAME (decl
) != NULL
715 && strcmp (DECL_SECTION_NAME (decl
),
716 TREE_STRING_POINTER (TREE_VALUE (args
))) != 0)
718 error ("section of %q+D conflicts with previous declaration",
720 *no_add_attrs
= true;
722 else if (VAR_P (decl
)
723 && !targetm
.have_tls
&& targetm
.emutls
.tmpl_section
724 && DECL_THREAD_LOCAL_P (decl
))
726 error ("section of %q+D cannot be overridden", *node
);
727 *no_add_attrs
= true;
730 set_decl_section_name (decl
,
731 TREE_STRING_POINTER (TREE_VALUE (args
)));
735 error ("section attribute not allowed for %q+D", *node
);
736 *no_add_attrs
= true;
741 error_at (DECL_SOURCE_LOCATION (*node
),
742 "section attributes are not supported for this target");
743 *no_add_attrs
= true;
749 /* Handle an "alias" attribute; arguments as in
750 struct attribute_spec.handler. */
753 d_handle_alias_attribute (tree
*node
, tree
ARG_UNUSED (name
),
754 tree args
, int ARG_UNUSED (flags
),
755 bool *no_add_attrs ATTRIBUTE_UNUSED
)
759 if (TREE_CODE (decl
) != FUNCTION_DECL
760 && TREE_CODE (decl
) != VAR_DECL
)
762 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
763 *no_add_attrs
= true;
766 else if ((TREE_CODE (decl
) == FUNCTION_DECL
&& DECL_INITIAL (decl
))
767 || (TREE_CODE (decl
) != FUNCTION_DECL
768 && TREE_PUBLIC (decl
) && !DECL_EXTERNAL (decl
))
769 /* A static variable declaration is always a tentative definition,
770 but the alias is a non-tentative definition which overrides. */
771 || (TREE_CODE (decl
) != FUNCTION_DECL
772 && ! TREE_PUBLIC (decl
) && DECL_INITIAL (decl
)))
774 error ("%q+D defined both normally and as %qE attribute", decl
, name
);
775 *no_add_attrs
= true;
778 else if (decl_function_context (decl
))
780 error ("%q+D alias functions must be global", name
);
781 *no_add_attrs
= true;
788 id
= TREE_VALUE (args
);
789 if (TREE_CODE (id
) != STRING_CST
)
791 error ("attribute %qE argument not a string", name
);
792 *no_add_attrs
= true;
795 id
= get_identifier (TREE_STRING_POINTER (id
));
796 /* This counts as a use of the object pointed to. */
799 if (TREE_CODE (decl
) == FUNCTION_DECL
)
800 DECL_INITIAL (decl
) = error_mark_node
;
802 TREE_STATIC (decl
) = 1;
808 /* Handle a "weak" attribute; arguments as in
809 struct attribute_spec.handler. */
812 d_handle_weak_attribute (tree
*node
, tree name
,
813 tree
ARG_UNUSED (args
),
814 int ARG_UNUSED (flags
),
815 bool * ARG_UNUSED (no_add_attrs
))
817 if (TREE_CODE (*node
) == FUNCTION_DECL
818 && DECL_DECLARED_INLINE_P (*node
))
820 warning (OPT_Wattributes
, "inline function %q+D declared weak", *node
);
821 *no_add_attrs
= true;
823 else if (VAR_OR_FUNCTION_DECL_P (*node
))
825 struct symtab_node
*n
= symtab_node::get (*node
);
826 if (n
&& n
->refuse_visibility_changes
)
827 error ("%q+D declared weak after being used", *node
);
828 declare_weak (*node
);
831 warning (OPT_Wattributes
, "%qE attribute ignored", name
);