attribs.c revision 96489
1/* Functions dealing with attribute handling, used by most front ends. 2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 3 2002 Free Software Foundation, Inc. 4 5This file is part of GCC. 6 7GCC is free software; you can redistribute it and/or modify it under 8the terms of the GNU General Public License as published by the Free 9Software Foundation; either version 2, or (at your option) any later 10version. 11 12GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13WARRANTY; without even the implied warranty of MERCHANTABILITY or 14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15for more details. 16 17You should have received a copy of the GNU General Public License 18along with GCC; see the file COPYING. If not, write to the Free 19Software Foundation, 59 Temple Place - Suite 330, Boston, MA 2002111-1307, USA. */ 21 22#include "config.h" 23#include "system.h" 24#include "tree.h" 25#include "flags.h" 26#include "toplev.h" 27#include "output.h" 28#include "rtl.h" 29#include "ggc.h" 30#include "expr.h" 31#include "tm_p.h" 32#include "obstack.h" 33#include "cpplib.h" 34#include "target.h" 35 36static void init_attributes PARAMS ((void)); 37 38/* Table of the tables of attributes (common, format, language, machine) 39 searched. */ 40static const struct attribute_spec *attribute_tables[4]; 41 42static bool attributes_initialized = false; 43 44static tree handle_packed_attribute PARAMS ((tree *, tree, tree, int, 45 bool *)); 46static tree handle_nocommon_attribute PARAMS ((tree *, tree, tree, int, 47 bool *)); 48static tree handle_common_attribute PARAMS ((tree *, tree, tree, int, 49 bool *)); 50static tree handle_noreturn_attribute PARAMS ((tree *, tree, tree, int, 51 bool *)); 52static tree handle_noinline_attribute PARAMS ((tree *, tree, tree, int, 53 bool *)); 54static tree handle_always_inline_attribute PARAMS ((tree *, tree, tree, int, 55 bool *)); 56static tree handle_used_attribute PARAMS ((tree *, tree, tree, int, 57 bool *)); 58static tree handle_unused_attribute PARAMS ((tree *, tree, tree, int, 59 bool *)); 60static tree handle_const_attribute PARAMS ((tree *, tree, tree, int, 61 bool *)); 62static tree handle_transparent_union_attribute PARAMS ((tree *, tree, tree, 63 int, bool *)); 64static tree handle_constructor_attribute PARAMS ((tree *, tree, tree, int, 65 bool *)); 66static tree handle_destructor_attribute PARAMS ((tree *, tree, tree, int, 67 bool *)); 68static tree handle_mode_attribute PARAMS ((tree *, tree, tree, int, 69 bool *)); 70static tree handle_section_attribute PARAMS ((tree *, tree, tree, int, 71 bool *)); 72static tree handle_aligned_attribute PARAMS ((tree *, tree, tree, int, 73 bool *)); 74static tree handle_weak_attribute PARAMS ((tree *, tree, tree, int, 75 bool *)); 76static tree handle_alias_attribute PARAMS ((tree *, tree, tree, int, 77 bool *)); 78static tree handle_no_instrument_function_attribute PARAMS ((tree *, tree, 79 tree, int, 80 bool *)); 81static tree handle_malloc_attribute PARAMS ((tree *, tree, tree, int, 82 bool *)); 83static tree handle_no_limit_stack_attribute PARAMS ((tree *, tree, tree, int, 84 bool *)); 85static tree handle_pure_attribute PARAMS ((tree *, tree, tree, int, 86 bool *)); 87static tree handle_deprecated_attribute PARAMS ((tree *, tree, tree, int, 88 bool *)); 89static tree handle_vector_size_attribute PARAMS ((tree *, tree, tree, int, 90 bool *)); 91static tree vector_size_helper PARAMS ((tree, tree)); 92 93/* Table of machine-independent attributes common to all C-like languages. */ 94static const struct attribute_spec c_common_attribute_table[] = 95{ 96 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ 97 { "packed", 0, 0, false, false, false, 98 handle_packed_attribute }, 99 { "nocommon", 0, 0, true, false, false, 100 handle_nocommon_attribute }, 101 { "common", 0, 0, true, false, false, 102 handle_common_attribute }, 103 /* FIXME: logically, noreturn attributes should be listed as 104 "false, true, true" and apply to function types. But implementing this 105 would require all the places in the compiler that use TREE_THIS_VOLATILE 106 on a decl to identify non-returning functions to be located and fixed 107 to check the function type instead. */ 108 { "noreturn", 0, 0, true, false, false, 109 handle_noreturn_attribute }, 110 { "volatile", 0, 0, true, false, false, 111 handle_noreturn_attribute }, 112 { "noinline", 0, 0, true, false, false, 113 handle_noinline_attribute }, 114 { "always_inline", 0, 0, true, false, false, 115 handle_always_inline_attribute }, 116 { "used", 0, 0, true, false, false, 117 handle_used_attribute }, 118 { "unused", 0, 0, false, false, false, 119 handle_unused_attribute }, 120 /* The same comments as for noreturn attributes apply to const ones. */ 121 { "const", 0, 0, true, false, false, 122 handle_const_attribute }, 123 { "transparent_union", 0, 0, false, false, false, 124 handle_transparent_union_attribute }, 125 { "constructor", 0, 0, true, false, false, 126 handle_constructor_attribute }, 127 { "destructor", 0, 0, true, false, false, 128 handle_destructor_attribute }, 129 { "mode", 1, 1, false, true, false, 130 handle_mode_attribute }, 131 { "section", 1, 1, true, false, false, 132 handle_section_attribute }, 133 { "aligned", 0, 1, false, false, false, 134 handle_aligned_attribute }, 135 { "weak", 0, 0, true, false, false, 136 handle_weak_attribute }, 137 { "alias", 1, 1, true, false, false, 138 handle_alias_attribute }, 139 { "no_instrument_function", 0, 0, true, false, false, 140 handle_no_instrument_function_attribute }, 141 { "malloc", 0, 0, true, false, false, 142 handle_malloc_attribute }, 143 { "no_stack_limit", 0, 0, true, false, false, 144 handle_no_limit_stack_attribute }, 145 { "pure", 0, 0, true, false, false, 146 handle_pure_attribute }, 147 { "deprecated", 0, 0, false, false, false, 148 handle_deprecated_attribute }, 149 { "vector_size", 1, 1, false, true, false, 150 handle_vector_size_attribute }, 151 { NULL, 0, 0, false, false, false, NULL } 152}; 153 154/* Default empty table of attributes. */ 155static const struct attribute_spec empty_attribute_table[] = 156{ 157 { NULL, 0, 0, false, false, false, NULL } 158}; 159 160/* Table of machine-independent attributes for checking formats, if used. */ 161const struct attribute_spec *format_attribute_table = empty_attribute_table; 162 163/* Table of machine-independent attributes for a particular language. */ 164const struct attribute_spec *lang_attribute_table = empty_attribute_table; 165 166/* Flag saying whether common language attributes are to be supported. */ 167int lang_attribute_common = 1; 168 169/* Initialize attribute tables, and make some sanity checks 170 if --enable-checking. */ 171 172static void 173init_attributes () 174{ 175#ifdef ENABLE_CHECKING 176 int i; 177#endif 178 179 attribute_tables[0] 180 = lang_attribute_common ? c_common_attribute_table : empty_attribute_table; 181 attribute_tables[1] = lang_attribute_table; 182 attribute_tables[2] = format_attribute_table; 183 attribute_tables[3] = targetm.attribute_table; 184 185#ifdef ENABLE_CHECKING 186 /* Make some sanity checks on the attribute tables. */ 187 for (i = 0; 188 i < (int) (sizeof (attribute_tables) / sizeof (attribute_tables[0])); 189 i++) 190 { 191 int j; 192 193 for (j = 0; attribute_tables[i][j].name != NULL; j++) 194 { 195 /* The name must not begin and end with __. */ 196 const char *name = attribute_tables[i][j].name; 197 int len = strlen (name); 198 if (name[0] == '_' && name[1] == '_' 199 && name[len - 1] == '_' && name[len - 2] == '_') 200 abort (); 201 /* The minimum and maximum lengths must be consistent. */ 202 if (attribute_tables[i][j].min_length < 0) 203 abort (); 204 if (attribute_tables[i][j].max_length != -1 205 && (attribute_tables[i][j].max_length 206 < attribute_tables[i][j].min_length)) 207 abort (); 208 /* An attribute cannot require both a DECL and a TYPE. */ 209 if (attribute_tables[i][j].decl_required 210 && attribute_tables[i][j].type_required) 211 abort (); 212 /* If an attribute requires a function type, in particular 213 it requires a type. */ 214 if (attribute_tables[i][j].function_type_required 215 && !attribute_tables[i][j].type_required) 216 abort (); 217 } 218 } 219 220 /* Check that each name occurs just once in each table. */ 221 for (i = 0; 222 i < (int) (sizeof (attribute_tables) / sizeof (attribute_tables[0])); 223 i++) 224 { 225 int j, k; 226 for (j = 0; attribute_tables[i][j].name != NULL; j++) 227 for (k = j + 1; attribute_tables[i][k].name != NULL; k++) 228 if (!strcmp (attribute_tables[i][j].name, 229 attribute_tables[i][k].name)) 230 abort (); 231 } 232 /* Check that no name occurs in more than one table. */ 233 for (i = 0; 234 i < (int) (sizeof (attribute_tables) / sizeof (attribute_tables[0])); 235 i++) 236 { 237 int j, k, l; 238 239 for (j = i + 1; 240 j < ((int) (sizeof (attribute_tables) 241 / sizeof (attribute_tables[0]))); 242 j++) 243 for (k = 0; attribute_tables[i][k].name != NULL; k++) 244 for (l = 0; attribute_tables[j][l].name != NULL; l++) 245 if (!strcmp (attribute_tables[i][k].name, 246 attribute_tables[j][l].name)) 247 abort (); 248 } 249#endif 250 251 attributes_initialized = true; 252} 253 254/* Process the attributes listed in ATTRIBUTES and install them in *NODE, 255 which is either a DECL (including a TYPE_DECL) or a TYPE. If a DECL, 256 it should be modified in place; if a TYPE, a copy should be created 257 unless ATTR_FLAG_TYPE_IN_PLACE is set in FLAGS. FLAGS gives further 258 information, in the form of a bitwise OR of flags in enum attribute_flags 259 from tree.h. Depending on these flags, some attributes may be 260 returned to be applied at a later stage (for example, to apply 261 a decl attribute to the declaration rather than to its type). If 262 ATTR_FLAG_BUILT_IN is not set and *NODE is a DECL, then also consider 263 whether there might be some default attributes to apply to this DECL; 264 if so, decl_attributes will be called recursively with those attributes 265 and ATTR_FLAG_BUILT_IN set. */ 266 267tree 268decl_attributes (node, attributes, flags) 269 tree *node, attributes; 270 int flags; 271{ 272 tree a; 273 tree returned_attrs = NULL_TREE; 274 275 if (!attributes_initialized) 276 init_attributes (); 277 278 (*targetm.insert_attributes) (*node, &attributes); 279 280 if (DECL_P (*node) && TREE_CODE (*node) == FUNCTION_DECL 281 && !(flags & (int) ATTR_FLAG_BUILT_IN)) 282 insert_default_attributes (*node); 283 284 for (a = attributes; a; a = TREE_CHAIN (a)) 285 { 286 tree name = TREE_PURPOSE (a); 287 tree args = TREE_VALUE (a); 288 tree *anode = node; 289 const struct attribute_spec *spec = NULL; 290 bool no_add_attrs = 0; 291 int i; 292 293 for (i = 0; 294 i < ((int) (sizeof (attribute_tables) 295 / sizeof (attribute_tables[0]))); 296 i++) 297 { 298 int j; 299 300 for (j = 0; attribute_tables[i][j].name != NULL; j++) 301 { 302 if (is_attribute_p (attribute_tables[i][j].name, name)) 303 { 304 spec = &attribute_tables[i][j]; 305 break; 306 } 307 } 308 if (spec != NULL) 309 break; 310 } 311 312 if (spec == NULL) 313 { 314 warning ("`%s' attribute directive ignored", 315 IDENTIFIER_POINTER (name)); 316 continue; 317 } 318 else if (list_length (args) < spec->min_length 319 || (spec->max_length >= 0 320 && list_length (args) > spec->max_length)) 321 { 322 error ("wrong number of arguments specified for `%s' attribute", 323 IDENTIFIER_POINTER (name)); 324 continue; 325 } 326 327 if (spec->decl_required && !DECL_P (*anode)) 328 { 329 if (flags & ((int) ATTR_FLAG_DECL_NEXT 330 | (int) ATTR_FLAG_FUNCTION_NEXT 331 | (int) ATTR_FLAG_ARRAY_NEXT)) 332 { 333 /* Pass on this attribute to be tried again. */ 334 returned_attrs = tree_cons (name, args, returned_attrs); 335 continue; 336 } 337 else 338 { 339 warning ("`%s' attribute does not apply to types", 340 IDENTIFIER_POINTER (name)); 341 continue; 342 } 343 } 344 345 /* If we require a type, but were passed a decl, set up to make a 346 new type and update the one in the decl. ATTR_FLAG_TYPE_IN_PLACE 347 would have applied if we'd been passed a type, but we cannot modify 348 the decl's type in place here. */ 349 if (spec->type_required && DECL_P (*anode)) 350 { 351 anode = &TREE_TYPE (*anode); 352 flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE; 353 } 354 355 if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE 356 && TREE_CODE (*anode) != METHOD_TYPE) 357 { 358 if (TREE_CODE (*anode) == POINTER_TYPE 359 && (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE 360 || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE)) 361 { 362 if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) 363 *anode = build_type_copy (*anode); 364 anode = &TREE_TYPE (*anode); 365 } 366 else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT) 367 { 368 /* Pass on this attribute to be tried again. */ 369 returned_attrs = tree_cons (name, args, returned_attrs); 370 continue; 371 } 372 373 if (TREE_CODE (*anode) != FUNCTION_TYPE 374 && TREE_CODE (*anode) != METHOD_TYPE) 375 { 376 warning ("`%s' attribute only applies to function types", 377 IDENTIFIER_POINTER (name)); 378 continue; 379 } 380 } 381 382 if (spec->handler != NULL) 383 returned_attrs = chainon ((*spec->handler) (anode, name, args, 384 flags, &no_add_attrs), 385 returned_attrs); 386 387 /* Layout the decl in case anything changed. */ 388 if (spec->type_required && DECL_P (*node) 389 && (TREE_CODE (*node) == VAR_DECL 390 || TREE_CODE (*node) == PARM_DECL 391 || TREE_CODE (*node) == RESULT_DECL)) 392 { 393 /* Force a recalculation of mode and size. */ 394 DECL_MODE (*node) = VOIDmode; 395 DECL_SIZE (*node) = 0; 396 397 layout_decl (*node, 0); 398 } 399 400 if (!no_add_attrs) 401 { 402 tree old_attrs; 403 tree a; 404 405 if (DECL_P (*anode)) 406 old_attrs = DECL_ATTRIBUTES (*anode); 407 else 408 old_attrs = TYPE_ATTRIBUTES (*anode); 409 410 for (a = lookup_attribute (spec->name, old_attrs); 411 a != NULL_TREE; 412 a = lookup_attribute (spec->name, TREE_CHAIN (a))) 413 { 414 if (simple_cst_equal (TREE_VALUE (a), args) == 1) 415 break; 416 } 417 418 if (a == NULL_TREE) 419 { 420 /* This attribute isn't already in the list. */ 421 if (DECL_P (*anode)) 422 DECL_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs); 423 else if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE) 424 TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs); 425 else 426 *anode = build_type_attribute_variant (*anode, 427 tree_cons (name, args, 428 old_attrs)); 429 } 430 } 431 } 432 433 return returned_attrs; 434} 435 436/* Handle a "packed" attribute; arguments as in 437 struct attribute_spec.handler. */ 438 439static tree 440handle_packed_attribute (node, name, args, flags, no_add_attrs) 441 tree *node; 442 tree name; 443 tree args ATTRIBUTE_UNUSED; 444 int flags; 445 bool *no_add_attrs; 446{ 447 tree *type = NULL; 448 if (DECL_P (*node)) 449 { 450 if (TREE_CODE (*node) == TYPE_DECL) 451 type = &TREE_TYPE (*node); 452 } 453 else 454 type = node; 455 456 if (type) 457 { 458 if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) 459 *type = build_type_copy (*type); 460 TYPE_PACKED (*type) = 1; 461 } 462 else if (TREE_CODE (*node) == FIELD_DECL) 463 DECL_PACKED (*node) = 1; 464 /* We can't set DECL_PACKED for a VAR_DECL, because the bit is 465 used for DECL_REGISTER. It wouldn't mean anything anyway. */ 466 else 467 { 468 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); 469 *no_add_attrs = true; 470 } 471 472 return NULL_TREE; 473} 474 475/* Handle a "nocommon" attribute; arguments as in 476 struct attribute_spec.handler. */ 477 478static tree 479handle_nocommon_attribute (node, name, args, flags, no_add_attrs) 480 tree *node; 481 tree name; 482 tree args ATTRIBUTE_UNUSED; 483 int flags ATTRIBUTE_UNUSED; 484 bool *no_add_attrs; 485{ 486 if (TREE_CODE (*node) == VAR_DECL) 487 DECL_COMMON (*node) = 0; 488 else 489 { 490 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); 491 *no_add_attrs = true; 492 } 493 494 return NULL_TREE; 495} 496 497/* Handle a "common" attribute; arguments as in 498 struct attribute_spec.handler. */ 499 500static tree 501handle_common_attribute (node, name, args, flags, no_add_attrs) 502 tree *node; 503 tree name; 504 tree args ATTRIBUTE_UNUSED; 505 int flags ATTRIBUTE_UNUSED; 506 bool *no_add_attrs; 507{ 508 if (TREE_CODE (*node) == VAR_DECL) 509 DECL_COMMON (*node) = 1; 510 else 511 { 512 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); 513 *no_add_attrs = true; 514 } 515 516 return NULL_TREE; 517} 518 519/* Handle a "noreturn" attribute; arguments as in 520 struct attribute_spec.handler. */ 521 522static tree 523handle_noreturn_attribute (node, name, args, flags, no_add_attrs) 524 tree *node; 525 tree name; 526 tree args ATTRIBUTE_UNUSED; 527 int flags ATTRIBUTE_UNUSED; 528 bool *no_add_attrs; 529{ 530 tree type = TREE_TYPE (*node); 531 532 /* See FIXME comment in c_common_attribute_table. */ 533 if (TREE_CODE (*node) == FUNCTION_DECL) 534 TREE_THIS_VOLATILE (*node) = 1; 535 else if (TREE_CODE (type) == POINTER_TYPE 536 && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE) 537 TREE_TYPE (*node) 538 = build_pointer_type 539 (build_type_variant (TREE_TYPE (type), 540 TREE_READONLY (TREE_TYPE (type)), 1)); 541 else 542 { 543 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); 544 *no_add_attrs = true; 545 } 546 547 return NULL_TREE; 548} 549 550/* Handle a "noinline" attribute; arguments as in 551 struct attribute_spec.handler. */ 552 553static tree 554handle_noinline_attribute (node, name, args, flags, no_add_attrs) 555 tree *node; 556 tree name; 557 tree args ATTRIBUTE_UNUSED; 558 int flags ATTRIBUTE_UNUSED; 559 bool *no_add_attrs; 560{ 561 if (TREE_CODE (*node) == FUNCTION_DECL) 562 DECL_UNINLINABLE (*node) = 1; 563 else 564 { 565 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); 566 *no_add_attrs = true; 567 } 568 569 return NULL_TREE; 570} 571 572/* Handle a "always_inline" attribute; arguments as in 573 struct attribute_spec.handler. */ 574 575static tree 576handle_always_inline_attribute (node, name, args, flags, no_add_attrs) 577 tree *node; 578 tree name; 579 tree args ATTRIBUTE_UNUSED; 580 int flags ATTRIBUTE_UNUSED; 581 bool *no_add_attrs; 582{ 583 if (TREE_CODE (*node) == FUNCTION_DECL) 584 { 585 /* Do nothing else, just set the attribute. We'll get at 586 it later with lookup_attribute. */ 587 } 588 else 589 { 590 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); 591 *no_add_attrs = true; 592 } 593 594 return NULL_TREE; 595} 596 597/* Handle a "used" attribute; arguments as in 598 struct attribute_spec.handler. */ 599 600static tree 601handle_used_attribute (node, name, args, flags, no_add_attrs) 602 tree *node; 603 tree name; 604 tree args ATTRIBUTE_UNUSED; 605 int flags ATTRIBUTE_UNUSED; 606 bool *no_add_attrs; 607{ 608 if (TREE_CODE (*node) == FUNCTION_DECL) 609 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (*node)) 610 = TREE_USED (*node) = 1; 611 else 612 { 613 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); 614 *no_add_attrs = true; 615 } 616 617 return NULL_TREE; 618} 619 620/* Handle a "unused" attribute; arguments as in 621 struct attribute_spec.handler. */ 622 623static tree 624handle_unused_attribute (node, name, args, flags, no_add_attrs) 625 tree *node; 626 tree name; 627 tree args ATTRIBUTE_UNUSED; 628 int flags; 629 bool *no_add_attrs; 630{ 631 if (DECL_P (*node)) 632 { 633 tree decl = *node; 634 635 if (TREE_CODE (decl) == PARM_DECL 636 || TREE_CODE (decl) == VAR_DECL 637 || TREE_CODE (decl) == FUNCTION_DECL 638 || TREE_CODE (decl) == LABEL_DECL 639 || TREE_CODE (decl) == TYPE_DECL) 640 TREE_USED (decl) = 1; 641 else 642 { 643 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); 644 *no_add_attrs = true; 645 } 646 } 647 else 648 { 649 if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) 650 *node = build_type_copy (*node); 651 TREE_USED (*node) = 1; 652 } 653 654 return NULL_TREE; 655} 656 657/* Handle a "const" attribute; arguments as in 658 struct attribute_spec.handler. */ 659 660static tree 661handle_const_attribute (node, name, args, flags, no_add_attrs) 662 tree *node; 663 tree name; 664 tree args ATTRIBUTE_UNUSED; 665 int flags ATTRIBUTE_UNUSED; 666 bool *no_add_attrs; 667{ 668 tree type = TREE_TYPE (*node); 669 670 /* See FIXME comment on noreturn in c_common_attribute_table. */ 671 if (TREE_CODE (*node) == FUNCTION_DECL) 672 TREE_READONLY (*node) = 1; 673 else if (TREE_CODE (type) == POINTER_TYPE 674 && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE) 675 TREE_TYPE (*node) 676 = build_pointer_type 677 (build_type_variant (TREE_TYPE (type), 1, 678 TREE_THIS_VOLATILE (TREE_TYPE (type)))); 679 else 680 { 681 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); 682 *no_add_attrs = true; 683 } 684 685 return NULL_TREE; 686} 687 688/* Handle a "transparent_union" attribute; arguments as in 689 struct attribute_spec.handler. */ 690 691static tree 692handle_transparent_union_attribute (node, name, args, flags, no_add_attrs) 693 tree *node; 694 tree name; 695 tree args ATTRIBUTE_UNUSED; 696 int flags; 697 bool *no_add_attrs; 698{ 699 tree decl = NULL_TREE; 700 tree *type = NULL; 701 int is_type = 0; 702 703 if (DECL_P (*node)) 704 { 705 decl = *node; 706 type = &TREE_TYPE (decl); 707 is_type = TREE_CODE (*node) == TYPE_DECL; 708 } 709 else if (TYPE_P (*node)) 710 type = node, is_type = 1; 711 712 if (is_type 713 && TREE_CODE (*type) == UNION_TYPE 714 && (decl == 0 715 || (TYPE_FIELDS (*type) != 0 716 && TYPE_MODE (*type) == DECL_MODE (TYPE_FIELDS (*type))))) 717 { 718 if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) 719 *type = build_type_copy (*type); 720 TYPE_TRANSPARENT_UNION (*type) = 1; 721 } 722 else if (decl != 0 && TREE_CODE (decl) == PARM_DECL 723 && TREE_CODE (*type) == UNION_TYPE 724 && TYPE_MODE (*type) == DECL_MODE (TYPE_FIELDS (*type))) 725 DECL_TRANSPARENT_UNION (decl) = 1; 726 else 727 { 728 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); 729 *no_add_attrs = true; 730 } 731 732 return NULL_TREE; 733} 734 735/* Handle a "constructor" attribute; arguments as in 736 struct attribute_spec.handler. */ 737 738static tree 739handle_constructor_attribute (node, name, args, flags, no_add_attrs) 740 tree *node; 741 tree name; 742 tree args ATTRIBUTE_UNUSED; 743 int flags ATTRIBUTE_UNUSED; 744 bool *no_add_attrs; 745{ 746 tree decl = *node; 747 tree type = TREE_TYPE (decl); 748 749 if (TREE_CODE (decl) == FUNCTION_DECL 750 && TREE_CODE (type) == FUNCTION_TYPE 751 && decl_function_context (decl) == 0) 752 { 753 DECL_STATIC_CONSTRUCTOR (decl) = 1; 754 TREE_USED (decl) = 1; 755 } 756 else 757 { 758 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); 759 *no_add_attrs = true; 760 } 761 762 return NULL_TREE; 763} 764 765/* Handle a "destructor" attribute; arguments as in 766 struct attribute_spec.handler. */ 767 768static tree 769handle_destructor_attribute (node, name, args, flags, no_add_attrs) 770 tree *node; 771 tree name; 772 tree args ATTRIBUTE_UNUSED; 773 int flags ATTRIBUTE_UNUSED; 774 bool *no_add_attrs; 775{ 776 tree decl = *node; 777 tree type = TREE_TYPE (decl); 778 779 if (TREE_CODE (decl) == FUNCTION_DECL 780 && TREE_CODE (type) == FUNCTION_TYPE 781 && decl_function_context (decl) == 0) 782 { 783 DECL_STATIC_DESTRUCTOR (decl) = 1; 784 TREE_USED (decl) = 1; 785 } 786 else 787 { 788 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); 789 *no_add_attrs = true; 790 } 791 792 return NULL_TREE; 793} 794 795/* Handle a "mode" attribute; arguments as in 796 struct attribute_spec.handler. */ 797 798static tree 799handle_mode_attribute (node, name, args, flags, no_add_attrs) 800 tree *node; 801 tree name; 802 tree args; 803 int flags ATTRIBUTE_UNUSED; 804 bool *no_add_attrs; 805{ 806 tree type = *node; 807 808 *no_add_attrs = true; 809 810 if (TREE_CODE (TREE_VALUE (args)) != IDENTIFIER_NODE) 811 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); 812 else 813 { 814 int j; 815 const char *p = IDENTIFIER_POINTER (TREE_VALUE (args)); 816 int len = strlen (p); 817 enum machine_mode mode = VOIDmode; 818 tree typefm; 819 820 if (len > 4 && p[0] == '_' && p[1] == '_' 821 && p[len - 1] == '_' && p[len - 2] == '_') 822 { 823 char *newp = (char *) alloca (len - 1); 824 825 strcpy (newp, &p[2]); 826 newp[len - 4] = '\0'; 827 p = newp; 828 } 829 830 /* Change this type to have a type with the specified mode. 831 First check for the special modes. */ 832 if (! strcmp (p, "byte")) 833 mode = byte_mode; 834 else if (!strcmp (p, "word")) 835 mode = word_mode; 836 else if (! strcmp (p, "pointer")) 837 mode = ptr_mode; 838 else 839 for (j = 0; j < NUM_MACHINE_MODES; j++) 840 if (!strcmp (p, GET_MODE_NAME (j))) 841 mode = (enum machine_mode) j; 842 843 if (mode == VOIDmode) 844 error ("unknown machine mode `%s'", p); 845 else if (0 == (typefm = type_for_mode (mode, 846 TREE_UNSIGNED (type)))) 847 error ("no data type for mode `%s'", p); 848 else 849 *node = typefm; 850 /* No need to layout the type here. The caller should do this. */ 851 } 852 853 return NULL_TREE; 854} 855 856/* Handle a "section" attribute; arguments as in 857 struct attribute_spec.handler. */ 858 859static tree 860handle_section_attribute (node, name, args, flags, no_add_attrs) 861 tree *node; 862 tree name ATTRIBUTE_UNUSED; 863 tree args; 864 int flags ATTRIBUTE_UNUSED; 865 bool *no_add_attrs; 866{ 867 tree decl = *node; 868 869 if (targetm.have_named_sections) 870 { 871 if ((TREE_CODE (decl) == FUNCTION_DECL 872 || TREE_CODE (decl) == VAR_DECL) 873 && TREE_CODE (TREE_VALUE (args)) == STRING_CST) 874 { 875 if (TREE_CODE (decl) == VAR_DECL 876 && current_function_decl != NULL_TREE 877 && ! TREE_STATIC (decl)) 878 { 879 error_with_decl (decl, 880 "section attribute cannot be specified for local variables"); 881 *no_add_attrs = true; 882 } 883 884 /* The decl may have already been given a section attribute 885 from a previous declaration. Ensure they match. */ 886 else if (DECL_SECTION_NAME (decl) != NULL_TREE 887 && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)), 888 TREE_STRING_POINTER (TREE_VALUE (args))) != 0) 889 { 890 error_with_decl (*node, 891 "section of `%s' conflicts with previous declaration"); 892 *no_add_attrs = true; 893 } 894 else 895 DECL_SECTION_NAME (decl) = TREE_VALUE (args); 896 } 897 else 898 { 899 error_with_decl (*node, 900 "section attribute not allowed for `%s'"); 901 *no_add_attrs = true; 902 } 903 } 904 else 905 { 906 error_with_decl (*node, 907 "section attributes are not supported for this target"); 908 *no_add_attrs = true; 909 } 910 911 return NULL_TREE; 912} 913 914/* Handle a "aligned" attribute; arguments as in 915 struct attribute_spec.handler. */ 916 917static tree 918handle_aligned_attribute (node, name, args, flags, no_add_attrs) 919 tree *node; 920 tree name ATTRIBUTE_UNUSED; 921 tree args; 922 int flags; 923 bool *no_add_attrs; 924{ 925 tree decl = NULL_TREE; 926 tree *type = NULL; 927 int is_type = 0; 928 tree align_expr = (args ? TREE_VALUE (args) 929 : size_int (BIGGEST_ALIGNMENT / BITS_PER_UNIT)); 930 int i; 931 932 if (DECL_P (*node)) 933 { 934 decl = *node; 935 type = &TREE_TYPE (decl); 936 is_type = TREE_CODE (*node) == TYPE_DECL; 937 } 938 else if (TYPE_P (*node)) 939 type = node, is_type = 1; 940 941 /* Strip any NOPs of any kind. */ 942 while (TREE_CODE (align_expr) == NOP_EXPR 943 || TREE_CODE (align_expr) == CONVERT_EXPR 944 || TREE_CODE (align_expr) == NON_LVALUE_EXPR) 945 align_expr = TREE_OPERAND (align_expr, 0); 946 947 if (TREE_CODE (align_expr) != INTEGER_CST) 948 { 949 error ("requested alignment is not a constant"); 950 *no_add_attrs = true; 951 } 952 else if ((i = tree_log2 (align_expr)) == -1) 953 { 954 error ("requested alignment is not a power of 2"); 955 *no_add_attrs = true; 956 } 957 else if (i > HOST_BITS_PER_INT - 2) 958 { 959 error ("requested alignment is too large"); 960 *no_add_attrs = true; 961 } 962 else if (is_type) 963 { 964 /* If we have a TYPE_DECL, then copy the type, so that we 965 don't accidentally modify a builtin type. See pushdecl. */ 966 if (decl && TREE_TYPE (decl) != error_mark_node 967 && DECL_ORIGINAL_TYPE (decl) == NULL_TREE) 968 { 969 tree tt = TREE_TYPE (decl); 970 *type = build_type_copy (*type); 971 DECL_ORIGINAL_TYPE (decl) = tt; 972 TYPE_NAME (*type) = decl; 973 TREE_USED (*type) = TREE_USED (decl); 974 TREE_TYPE (decl) = *type; 975 } 976 else if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) 977 *type = build_type_copy (*type); 978 979 TYPE_ALIGN (*type) = (1 << i) * BITS_PER_UNIT; 980 TYPE_USER_ALIGN (*type) = 1; 981 } 982 else if (TREE_CODE (decl) != VAR_DECL 983 && TREE_CODE (decl) != FIELD_DECL) 984 { 985 error_with_decl (decl, 986 "alignment may not be specified for `%s'"); 987 *no_add_attrs = true; 988 } 989 else 990 { 991 DECL_ALIGN (decl) = (1 << i) * BITS_PER_UNIT; 992 DECL_USER_ALIGN (decl) = 1; 993 } 994 995 return NULL_TREE; 996} 997 998/* Handle a "weak" attribute; arguments as in 999 struct attribute_spec.handler. */ 1000 1001static tree 1002handle_weak_attribute (node, name, args, flags, no_add_attrs) 1003 tree *node; 1004 tree name ATTRIBUTE_UNUSED; 1005 tree args ATTRIBUTE_UNUSED; 1006 int flags ATTRIBUTE_UNUSED; 1007 bool *no_add_attrs ATTRIBUTE_UNUSED; 1008{ 1009 declare_weak (*node); 1010 1011 return NULL_TREE; 1012} 1013 1014/* Handle an "alias" attribute; arguments as in 1015 struct attribute_spec.handler. */ 1016 1017static tree 1018handle_alias_attribute (node, name, args, flags, no_add_attrs) 1019 tree *node; 1020 tree name; 1021 tree args; 1022 int flags ATTRIBUTE_UNUSED; 1023 bool *no_add_attrs; 1024{ 1025 tree decl = *node; 1026 1027 if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl)) 1028 || (TREE_CODE (decl) != FUNCTION_DECL && ! DECL_EXTERNAL (decl))) 1029 { 1030 error_with_decl (decl, 1031 "`%s' defined both normally and as an alias"); 1032 *no_add_attrs = true; 1033 } 1034 else if (decl_function_context (decl) == 0) 1035 { 1036 tree id; 1037 1038 id = TREE_VALUE (args); 1039 if (TREE_CODE (id) != STRING_CST) 1040 { 1041 error ("alias arg not a string"); 1042 *no_add_attrs = true; 1043 return NULL_TREE; 1044 } 1045 id = get_identifier (TREE_STRING_POINTER (id)); 1046 /* This counts as a use of the object pointed to. */ 1047 TREE_USED (id) = 1; 1048 1049 if (TREE_CODE (decl) == FUNCTION_DECL) 1050 DECL_INITIAL (decl) = error_mark_node; 1051 else 1052 DECL_EXTERNAL (decl) = 0; 1053 assemble_alias (decl, id); 1054 } 1055 else 1056 { 1057 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); 1058 *no_add_attrs = true; 1059 } 1060 1061 return NULL_TREE; 1062} 1063 1064/* Handle a "no_instrument_function" attribute; arguments as in 1065 struct attribute_spec.handler. */ 1066 1067static tree 1068handle_no_instrument_function_attribute (node, name, args, flags, no_add_attrs) 1069 tree *node; 1070 tree name; 1071 tree args ATTRIBUTE_UNUSED; 1072 int flags ATTRIBUTE_UNUSED; 1073 bool *no_add_attrs; 1074{ 1075 tree decl = *node; 1076 1077 if (TREE_CODE (decl) != FUNCTION_DECL) 1078 { 1079 error_with_decl (decl, 1080 "`%s' attribute applies only to functions", 1081 IDENTIFIER_POINTER (name)); 1082 *no_add_attrs = true; 1083 } 1084 else if (DECL_INITIAL (decl)) 1085 { 1086 error_with_decl (decl, 1087 "can't set `%s' attribute after definition", 1088 IDENTIFIER_POINTER (name)); 1089 *no_add_attrs = true; 1090 } 1091 else 1092 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1; 1093 1094 return NULL_TREE; 1095} 1096 1097/* Handle a "malloc" attribute; arguments as in 1098 struct attribute_spec.handler. */ 1099 1100static tree 1101handle_malloc_attribute (node, name, args, flags, no_add_attrs) 1102 tree *node; 1103 tree name; 1104 tree args ATTRIBUTE_UNUSED; 1105 int flags ATTRIBUTE_UNUSED; 1106 bool *no_add_attrs; 1107{ 1108 if (TREE_CODE (*node) == FUNCTION_DECL) 1109 DECL_IS_MALLOC (*node) = 1; 1110 /* ??? TODO: Support types. */ 1111 else 1112 { 1113 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); 1114 *no_add_attrs = true; 1115 } 1116 1117 return NULL_TREE; 1118} 1119 1120/* Handle a "no_limit_stack" attribute; arguments as in 1121 struct attribute_spec.handler. */ 1122 1123static tree 1124handle_no_limit_stack_attribute (node, name, args, flags, no_add_attrs) 1125 tree *node; 1126 tree name; 1127 tree args ATTRIBUTE_UNUSED; 1128 int flags ATTRIBUTE_UNUSED; 1129 bool *no_add_attrs; 1130{ 1131 tree decl = *node; 1132 1133 if (TREE_CODE (decl) != FUNCTION_DECL) 1134 { 1135 error_with_decl (decl, 1136 "`%s' attribute applies only to functions", 1137 IDENTIFIER_POINTER (name)); 1138 *no_add_attrs = true; 1139 } 1140 else if (DECL_INITIAL (decl)) 1141 { 1142 error_with_decl (decl, 1143 "can't set `%s' attribute after definition", 1144 IDENTIFIER_POINTER (name)); 1145 *no_add_attrs = true; 1146 } 1147 else 1148 DECL_NO_LIMIT_STACK (decl) = 1; 1149 1150 return NULL_TREE; 1151} 1152 1153/* Handle a "pure" attribute; arguments as in 1154 struct attribute_spec.handler. */ 1155 1156static tree 1157handle_pure_attribute (node, name, args, flags, no_add_attrs) 1158 tree *node; 1159 tree name; 1160 tree args ATTRIBUTE_UNUSED; 1161 int flags ATTRIBUTE_UNUSED; 1162 bool *no_add_attrs; 1163{ 1164 if (TREE_CODE (*node) == FUNCTION_DECL) 1165 DECL_IS_PURE (*node) = 1; 1166 /* ??? TODO: Support types. */ 1167 else 1168 { 1169 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); 1170 *no_add_attrs = true; 1171 } 1172 1173 return NULL_TREE; 1174} 1175 1176/* Handle a "deprecated" attribute; arguments as in 1177 struct attribute_spec.handler. */ 1178 1179static tree 1180handle_deprecated_attribute (node, name, args, flags, no_add_attrs) 1181 tree *node; 1182 tree name; 1183 tree args ATTRIBUTE_UNUSED; 1184 int flags; 1185 bool *no_add_attrs; 1186{ 1187 tree type = NULL_TREE; 1188 int warn = 0; 1189 const char *what = NULL; 1190 1191 if (DECL_P (*node)) 1192 { 1193 tree decl = *node; 1194 type = TREE_TYPE (decl); 1195 1196 if (TREE_CODE (decl) == TYPE_DECL 1197 || TREE_CODE (decl) == PARM_DECL 1198 || TREE_CODE (decl) == VAR_DECL 1199 || TREE_CODE (decl) == FUNCTION_DECL 1200 || TREE_CODE (decl) == FIELD_DECL) 1201 TREE_DEPRECATED (decl) = 1; 1202 else 1203 warn = 1; 1204 } 1205 else if (TYPE_P (*node)) 1206 { 1207 if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) 1208 *node = build_type_copy (*node); 1209 TREE_DEPRECATED (*node) = 1; 1210 type = *node; 1211 } 1212 else 1213 warn = 1; 1214 1215 if (warn) 1216 { 1217 *no_add_attrs = true; 1218 if (type && TYPE_NAME (type)) 1219 { 1220 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) 1221 what = IDENTIFIER_POINTER (TYPE_NAME (*node)); 1222 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL 1223 && DECL_NAME (TYPE_NAME (type))) 1224 what = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); 1225 } 1226 if (what) 1227 warning ("`%s' attribute ignored for `%s'", 1228 IDENTIFIER_POINTER (name), what); 1229 else 1230 warning ("`%s' attribute ignored", 1231 IDENTIFIER_POINTER (name)); 1232 } 1233 1234 return NULL_TREE; 1235} 1236 1237/* Handle a "vector_size" attribute; arguments as in 1238 struct attribute_spec.handler. */ 1239 1240static tree 1241handle_vector_size_attribute (node, name, args, flags, no_add_attrs) 1242 tree *node; 1243 tree name; 1244 tree args; 1245 int flags ATTRIBUTE_UNUSED; 1246 bool *no_add_attrs; 1247{ 1248 unsigned HOST_WIDE_INT vecsize, nunits; 1249 enum machine_mode mode, orig_mode, new_mode; 1250 tree type = *node, new_type; 1251 1252 *no_add_attrs = true; 1253 1254 if (! host_integerp (TREE_VALUE (args), 1)) 1255 { 1256 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); 1257 return NULL_TREE; 1258 } 1259 1260 /* Get the vector size (in bytes). */ 1261 vecsize = tree_low_cst (TREE_VALUE (args), 1); 1262 1263 /* We need to provide for vector pointers, vector arrays, and 1264 functions returning vectors. For example: 1265 1266 __attribute__((vector_size(16))) short *foo; 1267 1268 In this case, the mode is SI, but the type being modified is 1269 HI, so we need to look further. */ 1270 1271 while (POINTER_TYPE_P (type) 1272 || TREE_CODE (type) == FUNCTION_TYPE 1273 || TREE_CODE (type) == ARRAY_TYPE) 1274 type = TREE_TYPE (type); 1275 1276 /* Get the mode of the type being modified. */ 1277 orig_mode = TYPE_MODE (type); 1278 1279 if (TREE_CODE (type) == RECORD_TYPE 1280 || (GET_MODE_CLASS (orig_mode) != MODE_FLOAT 1281 && GET_MODE_CLASS (orig_mode) != MODE_INT) 1282 || ! host_integerp (TYPE_SIZE_UNIT (type), 1)) 1283 { 1284 error ("invalid vector type for attribute `%s'", 1285 IDENTIFIER_POINTER (name)); 1286 return NULL_TREE; 1287 } 1288 1289 /* Calculate how many units fit in the vector. */ 1290 nunits = vecsize / tree_low_cst (TYPE_SIZE_UNIT (type), 1); 1291 1292 /* Find a suitably sized vector. */ 1293 new_mode = VOIDmode; 1294 for (mode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (orig_mode) == MODE_INT 1295 ? MODE_VECTOR_INT 1296 : MODE_VECTOR_FLOAT); 1297 mode != VOIDmode; 1298 mode = GET_MODE_WIDER_MODE (mode)) 1299 if (vecsize == GET_MODE_SIZE (mode) 1300 && nunits == (unsigned HOST_WIDE_INT) GET_MODE_NUNITS (mode)) 1301 { 1302 new_mode = mode; 1303 break; 1304 } 1305 1306 if (new_mode == VOIDmode) 1307 error ("no vector mode with the size and type specified could be found"); 1308 else 1309 { 1310 new_type = type_for_mode (new_mode, TREE_UNSIGNED (type)); 1311 if (!new_type) 1312 error ("no vector mode with the size and type specified could be found"); 1313 else 1314 /* Build back pointers if needed. */ 1315 *node = vector_size_helper (*node, new_type); 1316 } 1317 1318 return NULL_TREE; 1319} 1320 1321/* HACK. GROSS. This is absolutely disgusting. I wish there was a 1322 better way. 1323 1324 If we requested a pointer to a vector, build up the pointers that 1325 we stripped off while looking for the inner type. Similarly for 1326 return values from functions. 1327 1328 The argument "type" is the top of the chain, and "bottom" is the 1329 new type which we will point to. */ 1330 1331static tree 1332vector_size_helper (type, bottom) 1333 tree type, bottom; 1334{ 1335 tree inner, outer; 1336 1337 if (POINTER_TYPE_P (type)) 1338 { 1339 inner = vector_size_helper (TREE_TYPE (type), bottom); 1340 outer = build_pointer_type (inner); 1341 } 1342 else if (TREE_CODE (type) == ARRAY_TYPE) 1343 { 1344 inner = vector_size_helper (TREE_TYPE (type), bottom); 1345 outer = build_array_type (inner, TYPE_VALUES (type)); 1346 } 1347 else if (TREE_CODE (type) == FUNCTION_TYPE) 1348 { 1349 inner = vector_size_helper (TREE_TYPE (type), bottom); 1350 outer = build_function_type (inner, TYPE_VALUES (type)); 1351 } 1352 else 1353 return bottom; 1354 1355 TREE_READONLY (outer) = TREE_READONLY (type); 1356 TREE_THIS_VOLATILE (outer) = TREE_THIS_VOLATILE (type); 1357 1358 return outer; 1359} 1360 1361/* Split SPECS_ATTRS, a list of declspecs and prefix attributes, into two 1362 lists. SPECS_ATTRS may also be just a typespec (eg: RECORD_TYPE). 1363 1364 The head of the declspec list is stored in DECLSPECS. 1365 The head of the attribute list is stored in PREFIX_ATTRIBUTES. 1366 1367 Note that attributes in SPECS_ATTRS are stored in the TREE_PURPOSE of 1368 the list elements. We drop the containing TREE_LIST nodes and link the 1369 resulting attributes together the way decl_attributes expects them. */ 1370 1371void 1372split_specs_attrs (specs_attrs, declspecs, prefix_attributes) 1373 tree specs_attrs; 1374 tree *declspecs, *prefix_attributes; 1375{ 1376 tree t, s, a, next, specs, attrs; 1377 1378 /* This can happen after an __extension__ in pedantic mode. */ 1379 if (specs_attrs != NULL_TREE 1380 && TREE_CODE (specs_attrs) == INTEGER_CST) 1381 { 1382 *declspecs = NULL_TREE; 1383 *prefix_attributes = NULL_TREE; 1384 return; 1385 } 1386 1387 /* This can happen in c++ (eg: decl: typespec initdecls ';'). */ 1388 if (specs_attrs != NULL_TREE 1389 && TREE_CODE (specs_attrs) != TREE_LIST) 1390 { 1391 *declspecs = specs_attrs; 1392 *prefix_attributes = NULL_TREE; 1393 return; 1394 } 1395 1396 /* Remember to keep the lists in the same order, element-wise. */ 1397 1398 specs = s = NULL_TREE; 1399 attrs = a = NULL_TREE; 1400 for (t = specs_attrs; t; t = next) 1401 { 1402 next = TREE_CHAIN (t); 1403 /* Declspecs have a non-NULL TREE_VALUE. */ 1404 if (TREE_VALUE (t) != NULL_TREE) 1405 { 1406 if (specs == NULL_TREE) 1407 specs = s = t; 1408 else 1409 { 1410 TREE_CHAIN (s) = t; 1411 s = t; 1412 } 1413 } 1414 /* The TREE_PURPOSE may also be empty in the case of 1415 __attribute__(()). */ 1416 else if (TREE_PURPOSE (t) != NULL_TREE) 1417 { 1418 if (attrs == NULL_TREE) 1419 attrs = a = TREE_PURPOSE (t); 1420 else 1421 { 1422 TREE_CHAIN (a) = TREE_PURPOSE (t); 1423 a = TREE_PURPOSE (t); 1424 } 1425 /* More attrs can be linked here, move A to the end. */ 1426 while (TREE_CHAIN (a) != NULL_TREE) 1427 a = TREE_CHAIN (a); 1428 } 1429 } 1430 1431 /* Terminate the lists. */ 1432 if (s != NULL_TREE) 1433 TREE_CHAIN (s) = NULL_TREE; 1434 if (a != NULL_TREE) 1435 TREE_CHAIN (a) = NULL_TREE; 1436 1437 /* All done. */ 1438 *declspecs = specs; 1439 *prefix_attributes = attrs; 1440} 1441 1442/* Strip attributes from SPECS_ATTRS, a list of declspecs and attributes. 1443 This function is used by the parser when a rule will accept attributes 1444 in a particular position, but we don't want to support that just yet. 1445 1446 A warning is issued for every ignored attribute. */ 1447 1448tree 1449strip_attrs (specs_attrs) 1450 tree specs_attrs; 1451{ 1452 tree specs, attrs; 1453 1454 split_specs_attrs (specs_attrs, &specs, &attrs); 1455 1456 while (attrs) 1457 { 1458 warning ("`%s' attribute ignored", 1459 IDENTIFIER_POINTER (TREE_PURPOSE (attrs))); 1460 attrs = TREE_CHAIN (attrs); 1461 } 1462 1463 return specs; 1464} 1465 1466