]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/attribs.c
gcc/
[thirdparty/gcc.git] / gcc / attribs.c
CommitLineData
e3f6ce11 1/* Functions dealing with attribute handling, used by most front ends.
d353bf18 2 Copyright (C) 1992-2015 Free Software Foundation, Inc.
e3f6ce11 3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8c4c00c1 8Software Foundation; either version 3, or (at your option) any later
e3f6ce11 9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
8c4c00c1 17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
e3f6ce11 19
20#include "config.h"
21#include "system.h"
805e22b2 22#include "coretypes.h"
23#include "tm.h"
b20a8bb4 24#include "symtab.h"
b20a8bb4 25#include "alias.h"
e3f6ce11 26#include "tree.h"
9ed99284 27#include "stringpool.h"
28#include "attribs.h"
29#include "stor-layout.h"
e3f6ce11 30#include "flags.h"
0b205f4c 31#include "diagnostic-core.h"
e3f6ce11 32#include "tm_p.h"
e3f6ce11 33#include "cpplib.h"
34#include "target.h"
26ca6c20 35#include "langhooks.h"
e3fced1a 36#include "plugin.h"
e3f6ce11 37
f8e93a2e 38/* Table of the tables of attributes (common, language, format, machine)
e3f6ce11 39 searched. */
40static const struct attribute_spec *attribute_tables[4];
41
5b634bfa 42/* Substring representation. */
43
44struct substring
45{
46 const char *str;
47 int length;
48};
49
d9dd21a8 50/* Simple hash function to avoid need to scan whole string. */
51
52static inline hashval_t
53substring_hash (const char *str, int l)
54{
55 return str[0] + str[l - 1] * 256 + l * 65536;
56}
57
58/* Used for attribute_hash. */
59
60struct attribute_hasher : typed_noop_remove <attribute_spec>
61{
9969c043 62 typedef attribute_spec *value_type;
63 typedef substring *compare_type;
64 static inline hashval_t hash (const attribute_spec *);
65 static inline bool equal (const attribute_spec *, const substring *);
d9dd21a8 66};
67
68inline hashval_t
9969c043 69attribute_hasher::hash (const attribute_spec *spec)
d9dd21a8 70{
71 const int l = strlen (spec->name);
72 return substring_hash (spec->name, l);
73}
74
75inline bool
9969c043 76attribute_hasher::equal (const attribute_spec *spec, const substring *str)
d9dd21a8 77{
78 return (strncmp (spec->name, str->str, str->length) == 0
79 && !spec->name[str->length]);
80}
81
ffcdbf9c 82/* Scoped attribute name representation. */
83
84struct scoped_attributes
85{
86 const char *ns;
f1f41a6c 87 vec<attribute_spec> attributes;
c1f445d2 88 hash_table<attribute_hasher> *attribute_hash;
ffcdbf9c 89};
90
ffcdbf9c 91/* The table of scope attributes. */
f1f41a6c 92static vec<scoped_attributes> attributes_table;
ffcdbf9c 93
94static scoped_attributes* find_attribute_namespace (const char*);
95static void register_scoped_attribute (const struct attribute_spec *,
96 scoped_attributes *);
97
e3f6ce11 98static bool attributes_initialized = false;
99
e3f6ce11 100/* Default empty table of attributes. */
5b634bfa 101
e3f6ce11 102static const struct attribute_spec empty_attribute_table[] =
103{
ac86af5d 104 { NULL, 0, 0, false, false, false, NULL, false }
e3f6ce11 105};
106
5b634bfa 107/* Return base name of the attribute. Ie '__attr__' is turned into 'attr'.
108 To avoid need for copying, we simply return length of the string. */
109
110static void
111extract_attribute_substring (struct substring *str)
112{
113 if (str->length > 4 && str->str[0] == '_' && str->str[1] == '_'
114 && str->str[str->length - 1] == '_' && str->str[str->length - 2] == '_')
115 {
116 str->length -= 4;
117 str->str += 2;
118 }
119}
120
ffcdbf9c 121/* Insert an array of attributes ATTRIBUTES into a namespace. This
122 array must be NULL terminated. NS is the name of attribute
123 namespace. The function returns the namespace into which the
124 attributes have been registered. */
125
126scoped_attributes*
127register_scoped_attributes (const struct attribute_spec * attributes,
128 const char* ns)
129{
130 scoped_attributes *result = NULL;
131
132 /* See if we already have attributes in the namespace NS. */
133 result = find_attribute_namespace (ns);
134
135 if (result == NULL)
136 {
137 /* We don't have any namespace NS yet. Create one. */
138 scoped_attributes sa;
139
f1f41a6c 140 if (!attributes_table.is_empty ())
141 attributes_table.create (64);
ffcdbf9c 142
143 memset (&sa, 0, sizeof (sa));
144 sa.ns = ns;
f1f41a6c 145 sa.attributes.create (64);
146 result = attributes_table.safe_push (sa);
c1f445d2 147 result->attribute_hash = new hash_table<attribute_hasher> (200);
ffcdbf9c 148 }
149
150 /* Really add the attributes to their namespace now. */
151 for (unsigned i = 0; attributes[i].name != NULL; ++i)
152 {
f1f41a6c 153 result->attributes.safe_push (attributes[i]);
ffcdbf9c 154 register_scoped_attribute (&attributes[i], result);
155 }
156
157 gcc_assert (result != NULL);
158
159 return result;
160}
161
162/* Return the namespace which name is NS, NULL if none exist. */
163
164static scoped_attributes*
165find_attribute_namespace (const char* ns)
166{
167 unsigned ix;
168 scoped_attributes *iter;
169
f1f41a6c 170 FOR_EACH_VEC_ELT (attributes_table, ix, iter)
ffcdbf9c 171 if (ns == iter->ns
172 || (iter->ns != NULL
173 && ns != NULL
174 && !strcmp (iter->ns, ns)))
175 return iter;
176 return NULL;
177}
178
e3f6ce11 179/* Initialize attribute tables, and make some sanity checks
180 if --enable-checking. */
181
b7831f3e 182void
aecda0d6 183init_attributes (void)
e3f6ce11 184{
3585dac7 185 size_t i;
e3f6ce11 186
b7831f3e 187 if (attributes_initialized)
188 return;
189
f8e93a2e 190 attribute_tables[0] = lang_hooks.common_attribute_table;
191 attribute_tables[1] = lang_hooks.attribute_table;
192 attribute_tables[2] = lang_hooks.format_attribute_table;
e3f6ce11 193 attribute_tables[3] = targetm.attribute_table;
194
f8e93a2e 195 /* Translate NULL pointers to pointers to the empty table. */
196 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
197 if (attribute_tables[i] == NULL)
198 attribute_tables[i] = empty_attribute_table;
199
e3f6ce11 200#ifdef ENABLE_CHECKING
201 /* Make some sanity checks on the attribute tables. */
3585dac7 202 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
e3f6ce11 203 {
204 int j;
205
206 for (j = 0; attribute_tables[i][j].name != NULL; j++)
207 {
208 /* The name must not begin and end with __. */
209 const char *name = attribute_tables[i][j].name;
210 int len = strlen (name);
a0c938f0 211
64db345d 212 gcc_assert (!(name[0] == '_' && name[1] == '_'
213 && name[len - 1] == '_' && name[len - 2] == '_'));
a0c938f0 214
e3f6ce11 215 /* The minimum and maximum lengths must be consistent. */
64db345d 216 gcc_assert (attribute_tables[i][j].min_length >= 0);
a0c938f0 217
64db345d 218 gcc_assert (attribute_tables[i][j].max_length == -1
219 || (attribute_tables[i][j].max_length
220 >= attribute_tables[i][j].min_length));
a0c938f0 221
e3f6ce11 222 /* An attribute cannot require both a DECL and a TYPE. */
64db345d 223 gcc_assert (!attribute_tables[i][j].decl_required
224 || !attribute_tables[i][j].type_required);
a0c938f0 225
e3f6ce11 226 /* If an attribute requires a function type, in particular
227 it requires a type. */
64db345d 228 gcc_assert (!attribute_tables[i][j].function_type_required
229 || attribute_tables[i][j].type_required);
e3f6ce11 230 }
231 }
232
233 /* Check that each name occurs just once in each table. */
3585dac7 234 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
e3f6ce11 235 {
236 int j, k;
237 for (j = 0; attribute_tables[i][j].name != NULL; j++)
238 for (k = j + 1; attribute_tables[i][k].name != NULL; k++)
64db345d 239 gcc_assert (strcmp (attribute_tables[i][j].name,
240 attribute_tables[i][k].name));
e3f6ce11 241 }
4c0315d0 242 /* Check that no name occurs in more than one table. Names that
243 begin with '*' are exempt, and may be overridden. */
3585dac7 244 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
e3f6ce11 245 {
3585dac7 246 size_t j, k, l;
e3f6ce11 247
3585dac7 248 for (j = i + 1; j < ARRAY_SIZE (attribute_tables); j++)
e3f6ce11 249 for (k = 0; attribute_tables[i][k].name != NULL; k++)
250 for (l = 0; attribute_tables[j][l].name != NULL; l++)
4c0315d0 251 gcc_assert (attribute_tables[i][k].name[0] == '*'
252 || strcmp (attribute_tables[i][k].name,
253 attribute_tables[j][l].name));
e3f6ce11 254 }
255#endif
256
ffcdbf9c 257 for (i = 0; i < ARRAY_SIZE (attribute_tables); ++i)
258 /* Put all the GNU attributes into the "gnu" namespace. */
259 register_scoped_attributes (attribute_tables[i], "gnu");
260
e3fced1a 261 invoke_plugin_callbacks (PLUGIN_ATTRIBUTES, NULL);
262 attributes_initialized = true;
263}
264
265/* Insert a single ATTR into the attribute table. */
266
267void
48e1416a 268register_attribute (const struct attribute_spec *attr)
ffcdbf9c 269{
270 register_scoped_attribute (attr, find_attribute_namespace ("gnu"));
271}
272
273/* Insert a single attribute ATTR into a namespace of attributes. */
274
275static void
276register_scoped_attribute (const struct attribute_spec *attr,
277 scoped_attributes *name_space)
e3fced1a 278{
4fb84273 279 struct substring str;
d9dd21a8 280 attribute_spec **slot;
4fb84273 281
ffcdbf9c 282 gcc_assert (attr != NULL && name_space != NULL);
283
c1f445d2 284 gcc_assert (name_space->attribute_hash);
ffcdbf9c 285
4fb84273 286 str.str = attr->name;
287 str.length = strlen (str.str);
c55c785f 288
289 /* Attribute names in the table must be in the form 'text' and not
290 in the form '__text__'. */
291 gcc_assert (str.length > 0 && str.str[0] != '_');
292
d9dd21a8 293 slot = name_space->attribute_hash
c1f445d2 294 ->find_slot_with_hash (&str, substring_hash (str.str, str.length),
295 INSERT);
4c0315d0 296 gcc_assert (!*slot || attr->name[0] == '*');
d9dd21a8 297 *slot = CONST_CAST (struct attribute_spec *, attr);
e3f6ce11 298}
2fdd6488 299
ffcdbf9c 300/* Return the spec for the scoped attribute with namespace NS and
301 name NAME. */
2fdd6488 302
0e80b01d 303static const struct attribute_spec *
ffcdbf9c 304lookup_scoped_attribute_spec (const_tree ns, const_tree name)
2fdd6488 305{
306 struct substring attr;
ffcdbf9c 307 scoped_attributes *attrs;
308
309 const char *ns_str = (ns != NULL_TREE) ? IDENTIFIER_POINTER (ns): NULL;
310
311 attrs = find_attribute_namespace (ns_str);
312
313 if (attrs == NULL)
314 return NULL;
2fdd6488 315
316 attr.str = IDENTIFIER_POINTER (name);
317 attr.length = IDENTIFIER_LENGTH (name);
318 extract_attribute_substring (&attr);
c1f445d2 319 return attrs->attribute_hash->find_with_hash (&attr,
320 substring_hash (attr.str,
321 attr.length));
2fdd6488 322}
ffcdbf9c 323
d4701f6c 324/* Return the spec for the attribute named NAME. If NAME is a TREE_LIST,
325 it also specifies the attribute namespace. */
ffcdbf9c 326
327const struct attribute_spec *
328lookup_attribute_spec (const_tree name)
329{
d4701f6c 330 tree ns;
331 if (TREE_CODE (name) == TREE_LIST)
332 {
333 ns = TREE_PURPOSE (name);
334 name = TREE_VALUE (name);
335 }
336 else
337 ns = get_identifier ("gnu");
338 return lookup_scoped_attribute_spec (ns, name);
ffcdbf9c 339}
340
0e80b01d 341
342/* Return the namespace of the attribute ATTR. This accessor works on
343 GNU and C++11 (scoped) attributes. On GNU attributes,
344 it returns an identifier tree for the string "gnu".
345
346 Please read the comments of cxx11_attribute_p to understand the
347 format of attributes. */
348
349static tree
350get_attribute_namespace (const_tree attr)
351{
352 if (cxx11_attribute_p (attr))
353 return TREE_PURPOSE (TREE_PURPOSE (attr));
354 return get_identifier ("gnu");
355}
356
357
e3f6ce11 358/* Process the attributes listed in ATTRIBUTES and install them in *NODE,
359 which is either a DECL (including a TYPE_DECL) or a TYPE. If a DECL,
360 it should be modified in place; if a TYPE, a copy should be created
361 unless ATTR_FLAG_TYPE_IN_PLACE is set in FLAGS. FLAGS gives further
362 information, in the form of a bitwise OR of flags in enum attribute_flags
363 from tree.h. Depending on these flags, some attributes may be
364 returned to be applied at a later stage (for example, to apply
101cc430 365 a decl attribute to the declaration rather than to its type). */
e3f6ce11 366
367tree
aecda0d6 368decl_attributes (tree *node, tree attributes, int flags)
e3f6ce11 369{
370 tree a;
371 tree returned_attrs = NULL_TREE;
372
ffcdbf9c 373 if (TREE_TYPE (*node) == error_mark_node || attributes == error_mark_node)
1ccba7b7 374 return NULL_TREE;
375
e3f6ce11 376 if (!attributes_initialized)
377 init_attributes ();
378
46f8e3b0 379 /* If this is a function and the user used #pragma GCC optimize, add the
380 options to the attribute((optimize(...))) list. */
381 if (TREE_CODE (*node) == FUNCTION_DECL && current_optimize_pragma)
382 {
383 tree cur_attr = lookup_attribute ("optimize", attributes);
384 tree opts = copy_list (current_optimize_pragma);
385
386 if (! cur_attr)
387 attributes
388 = tree_cons (get_identifier ("optimize"), opts, attributes);
389 else
390 TREE_VALUE (cur_attr) = chainon (opts, TREE_VALUE (cur_attr));
391 }
392
393 if (TREE_CODE (*node) == FUNCTION_DECL
394 && optimization_current_node != optimization_default_node
395 && !DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node))
396 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node) = optimization_current_node;
397
24470055 398 /* If this is a function and the user used #pragma GCC target, add the
399 options to the attribute((target(...))) list. */
46f8e3b0 400 if (TREE_CODE (*node) == FUNCTION_DECL
24470055 401 && current_target_pragma
46f8e3b0 402 && targetm.target_option.valid_attribute_p (*node, NULL_TREE,
24470055 403 current_target_pragma, 0))
46f8e3b0 404 {
24470055 405 tree cur_attr = lookup_attribute ("target", attributes);
406 tree opts = copy_list (current_target_pragma);
46f8e3b0 407
408 if (! cur_attr)
24470055 409 attributes = tree_cons (get_identifier ("target"), opts, attributes);
46f8e3b0 410 else
411 TREE_VALUE (cur_attr) = chainon (opts, TREE_VALUE (cur_attr));
412 }
413
cd28ae7a 414 /* A "naked" function attribute implies "noinline" and "noclone" for
415 those targets that support it. */
416 if (TREE_CODE (*node) == FUNCTION_DECL
c55c785f 417 && attributes
cd28ae7a 418 && lookup_attribute_spec (get_identifier ("naked"))
419 && lookup_attribute ("naked", attributes) != NULL)
420 {
421 if (lookup_attribute ("noinline", attributes) == NULL)
422 attributes = tree_cons (get_identifier ("noinline"), NULL, attributes);
423
424 if (lookup_attribute ("noclone", attributes) == NULL)
425 attributes = tree_cons (get_identifier ("noclone"), NULL, attributes);
426 }
427
883b2e73 428 targetm.insert_attributes (*node, &attributes);
e3f6ce11 429
430 for (a = attributes; a; a = TREE_CHAIN (a))
431 {
ffcdbf9c 432 tree ns = get_attribute_namespace (a);
433 tree name = get_attribute_name (a);
e3f6ce11 434 tree args = TREE_VALUE (a);
435 tree *anode = node;
ffcdbf9c 436 const struct attribute_spec *spec =
437 lookup_scoped_attribute_spec (ns, name);
e3f6ce11 438 bool no_add_attrs = 0;
ce6dcb60 439 int fn_ptr_quals = 0;
79bdd5ff 440 tree fn_ptr_tmp = NULL_TREE;
e3f6ce11 441
442 if (spec == NULL)
443 {
c8010b80 444 if (!(flags & (int) ATTR_FLAG_BUILT_IN))
ffcdbf9c 445 {
446 if (ns == NULL_TREE || !cxx11_attribute_p (a))
447 warning (OPT_Wattributes, "%qE attribute directive ignored",
448 name);
449 else
450 warning (OPT_Wattributes,
451 "%<%E::%E%> scoped attribute directive ignored",
452 ns, name);
453 }
e3f6ce11 454 continue;
455 }
456 else if (list_length (args) < spec->min_length
457 || (spec->max_length >= 0
458 && list_length (args) > spec->max_length))
459 {
abd3e6b5 460 error ("wrong number of arguments specified for %qE attribute",
461 name);
e3f6ce11 462 continue;
463 }
5b634bfa 464 gcc_assert (is_attribute_p (spec->name, name));
e3f6ce11 465
ffcdbf9c 466 if (TYPE_P (*node)
467 && cxx11_attribute_p (a)
468 && !(flags & ATTR_FLAG_TYPE_IN_PLACE))
469 {
470 /* This is a c++11 attribute that appertains to a
471 type-specifier, outside of the definition of, a class
472 type. Ignore it. */
473 warning (OPT_Wattributes, "attribute ignored");
474 inform (input_location,
475 "an attribute that appertains to a type-specifier "
476 "is ignored");
477 continue;
478 }
479
e3f6ce11 480 if (spec->decl_required && !DECL_P (*anode))
481 {
482 if (flags & ((int) ATTR_FLAG_DECL_NEXT
483 | (int) ATTR_FLAG_FUNCTION_NEXT
484 | (int) ATTR_FLAG_ARRAY_NEXT))
485 {
486 /* Pass on this attribute to be tried again. */
487 returned_attrs = tree_cons (name, args, returned_attrs);
488 continue;
489 }
490 else
491 {
abd3e6b5 492 warning (OPT_Wattributes, "%qE attribute does not apply to types",
493 name);
e3f6ce11 494 continue;
495 }
496 }
497
aa9c60c1 498 /* If we require a type, but were passed a decl, set up to make a
499 new type and update the one in the decl. ATTR_FLAG_TYPE_IN_PLACE
500 would have applied if we'd been passed a type, but we cannot modify
501 the decl's type in place here. */
e3f6ce11 502 if (spec->type_required && DECL_P (*anode))
aa9c60c1 503 {
504 anode = &TREE_TYPE (*anode);
b0dc5308 505 flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
aa9c60c1 506 }
e3f6ce11 507
508 if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE
509 && TREE_CODE (*anode) != METHOD_TYPE)
510 {
511 if (TREE_CODE (*anode) == POINTER_TYPE
512 && (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE
513 || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE))
514 {
79bdd5ff 515 /* OK, this is a bit convoluted. We can't just make a copy
516 of the pointer type and modify its TREE_TYPE, because if
517 we change the attributes of the target type the pointer
518 type needs to have a different TYPE_MAIN_VARIANT. So we
519 pull out the target type now, frob it as appropriate, and
520 rebuild the pointer type later.
521
a0c938f0 522 This would all be simpler if attributes were part of the
523 declarator, grumble grumble. */
79bdd5ff 524 fn_ptr_tmp = TREE_TYPE (*anode);
ce6dcb60 525 fn_ptr_quals = TYPE_QUALS (*anode);
79bdd5ff 526 anode = &fn_ptr_tmp;
527 flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
e3f6ce11 528 }
529 else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
530 {
531 /* Pass on this attribute to be tried again. */
532 returned_attrs = tree_cons (name, args, returned_attrs);
533 continue;
534 }
535
536 if (TREE_CODE (*anode) != FUNCTION_TYPE
537 && TREE_CODE (*anode) != METHOD_TYPE)
538 {
9b2d6d13 539 warning (OPT_Wattributes,
abd3e6b5 540 "%qE attribute only applies to function types",
541 name);
e3f6ce11 542 continue;
543 }
544 }
545
4a2849cb 546 if (TYPE_P (*anode)
547 && (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
548 && TYPE_SIZE (*anode) != NULL_TREE)
549 {
550 warning (OPT_Wattributes, "type attributes ignored after type is already defined");
551 continue;
552 }
553
e3f6ce11 554 if (spec->handler != NULL)
ffcdbf9c 555 {
556 int cxx11_flag =
557 cxx11_attribute_p (a) ? ATTR_FLAG_CXX11 : 0;
558
559 returned_attrs = chainon ((*spec->handler) (anode, name, args,
560 flags|cxx11_flag,
561 &no_add_attrs),
562 returned_attrs);
563 }
ae4718db 564
565 /* Layout the decl in case anything changed. */
566 if (spec->type_required && DECL_P (*node)
e56de52f 567 && (TREE_CODE (*node) == VAR_DECL
568 || TREE_CODE (*node) == PARM_DECL
569 || TREE_CODE (*node) == RESULT_DECL))
1c0a6d1e 570 relayout_decl (*node);
ae4718db 571
e3f6ce11 572 if (!no_add_attrs)
573 {
574 tree old_attrs;
575 tree a;
576
577 if (DECL_P (*anode))
578 old_attrs = DECL_ATTRIBUTES (*anode);
579 else
580 old_attrs = TYPE_ATTRIBUTES (*anode);
581
582 for (a = lookup_attribute (spec->name, old_attrs);
583 a != NULL_TREE;
584 a = lookup_attribute (spec->name, TREE_CHAIN (a)))
585 {
586 if (simple_cst_equal (TREE_VALUE (a), args) == 1)
587 break;
588 }
589
590 if (a == NULL_TREE)
591 {
592 /* This attribute isn't already in the list. */
593 if (DECL_P (*anode))
594 DECL_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
595 else if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
316e17ae 596 {
597 TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
598 /* If this is the main variant, also push the attributes
599 out to the other variants. */
600 if (*anode == TYPE_MAIN_VARIANT (*anode))
601 {
602 tree variant;
603 for (variant = *anode; variant;
604 variant = TYPE_NEXT_VARIANT (variant))
605 {
606 if (TYPE_ATTRIBUTES (variant) == old_attrs)
607 TYPE_ATTRIBUTES (variant)
608 = TYPE_ATTRIBUTES (*anode);
609 else if (!lookup_attribute
610 (spec->name, TYPE_ATTRIBUTES (variant)))
611 TYPE_ATTRIBUTES (variant) = tree_cons
612 (name, args, TYPE_ATTRIBUTES (variant));
613 }
614 }
615 }
e3f6ce11 616 else
617 *anode = build_type_attribute_variant (*anode,
618 tree_cons (name, args,
619 old_attrs));
620 }
621 }
79bdd5ff 622
623 if (fn_ptr_tmp)
624 {
625 /* Rebuild the function pointer type and put it in the
626 appropriate place. */
627 fn_ptr_tmp = build_pointer_type (fn_ptr_tmp);
ce6dcb60 628 if (fn_ptr_quals)
629 fn_ptr_tmp = build_qualified_type (fn_ptr_tmp, fn_ptr_quals);
79bdd5ff 630 if (DECL_P (*node))
631 TREE_TYPE (*node) = fn_ptr_tmp;
79bdd5ff 632 else
64db345d 633 {
634 gcc_assert (TREE_CODE (*node) == POINTER_TYPE);
635 *node = fn_ptr_tmp;
636 }
79bdd5ff 637 }
e3f6ce11 638 }
639
640 return returned_attrs;
641}
4c0315d0 642
ffcdbf9c 643/* Return TRUE iff ATTR has been parsed by the front-end as a C++-11
644 attribute.
645
646 When G++ parses a C++11 attribute, it is represented as
647 a TREE_LIST which TREE_PURPOSE is itself a TREE_LIST. TREE_PURPOSE
648 (TREE_PURPOSE (ATTR)) is the namespace of the attribute, and the
649 TREE_VALUE (TREE_PURPOSE (ATTR)) is its non-qualified name. Please
650 use get_attribute_namespace and get_attribute_name to retrieve the
651 namespace and name of the attribute, as these accessors work with
652 GNU attributes as well. */
653
654bool
655cxx11_attribute_p (const_tree attr)
656{
657 if (attr == NULL_TREE
658 || TREE_CODE (attr) != TREE_LIST)
659 return false;
660
661 return (TREE_CODE (TREE_PURPOSE (attr)) == TREE_LIST);
662}
663
664/* Return the name of the attribute ATTR. This accessor works on GNU
665 and C++11 (scoped) attributes.
666
667 Please read the comments of cxx11_attribute_p to understand the
668 format of attributes. */
669
670tree
671get_attribute_name (const_tree attr)
672{
673 if (cxx11_attribute_p (attr))
674 return TREE_VALUE (TREE_PURPOSE (attr));
675 return TREE_PURPOSE (attr);
676}
677
4c0315d0 678/* Subroutine of set_method_tm_attributes. Apply TM attribute ATTR
679 to the method FNDECL. */
680
681void
682apply_tm_attr (tree fndecl, tree attr)
683{
684 decl_attributes (&TREE_TYPE (fndecl), tree_cons (attr, NULL, NULL), 0);
685}