attribs.c revision 102780
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 } 1054 else 1055 { 1056 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); 1057 *no_add_attrs = true; 1058 } 1059 1060 return NULL_TREE; 1061} 1062 1063/* Handle a "no_instrument_function" attribute; arguments as in 1064 struct attribute_spec.handler. */ 1065 1066static tree 1067handle_no_instrument_function_attribute (node, name, args, flags, no_add_attrs) 1068 tree *node; 1069 tree name; 1070 tree args ATTRIBUTE_UNUSED; 1071 int flags ATTRIBUTE_UNUSED; 1072 bool *no_add_attrs; 1073{ 1074 tree decl = *node; 1075 1076 if (TREE_CODE (decl) != FUNCTION_DECL) 1077 { 1078 error_with_decl (decl, 1079 "`%s' attribute applies only to functions", 1080 IDENTIFIER_POINTER (name)); 1081 *no_add_attrs = true; 1082 } 1083 else if (DECL_INITIAL (decl)) 1084 { 1085 error_with_decl (decl, 1086 "can't set `%s' attribute after definition", 1087 IDENTIFIER_POINTER (name)); 1088 *no_add_attrs = true; 1089 } 1090 else 1091 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1; 1092 1093 return NULL_TREE; 1094} 1095 1096/* Handle a "malloc" attribute; arguments as in 1097 struct attribute_spec.handler. */ 1098 1099static tree 1100handle_malloc_attribute (node, name, args, flags, no_add_attrs) 1101 tree *node; 1102 tree name; 1103 tree args ATTRIBUTE_UNUSED; 1104 int flags ATTRIBUTE_UNUSED; 1105 bool *no_add_attrs; 1106{ 1107 if (TREE_CODE (*node) == FUNCTION_DECL) 1108 DECL_IS_MALLOC (*node) = 1; 1109 /* ??? TODO: Support types. */ 1110 else 1111 { 1112 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); 1113 *no_add_attrs = true; 1114 } 1115 1116 return NULL_TREE; 1117} 1118 1119/* Handle a "no_limit_stack" attribute; arguments as in 1120 struct attribute_spec.handler. */ 1121 1122static tree 1123handle_no_limit_stack_attribute (node, name, args, flags, no_add_attrs) 1124 tree *node; 1125 tree name; 1126 tree args ATTRIBUTE_UNUSED; 1127 int flags ATTRIBUTE_UNUSED; 1128 bool *no_add_attrs; 1129{ 1130 tree decl = *node; 1131 1132 if (TREE_CODE (decl) != FUNCTION_DECL) 1133 { 1134 error_with_decl (decl, 1135 "`%s' attribute applies only to functions", 1136 IDENTIFIER_POINTER (name)); 1137 *no_add_attrs = true; 1138 } 1139 else if (DECL_INITIAL (decl)) 1140 { 1141 error_with_decl (decl, 1142 "can't set `%s' attribute after definition", 1143 IDENTIFIER_POINTER (name)); 1144 *no_add_attrs = true; 1145 } 1146 else 1147 DECL_NO_LIMIT_STACK (decl) = 1; 1148 1149 return NULL_TREE; 1150} 1151 1152/* Handle a "pure" attribute; arguments as in 1153 struct attribute_spec.handler. */ 1154 1155static tree 1156handle_pure_attribute (node, name, args, flags, no_add_attrs) 1157 tree *node; 1158 tree name; 1159 tree args ATTRIBUTE_UNUSED; 1160 int flags ATTRIBUTE_UNUSED; 1161 bool *no_add_attrs; 1162{ 1163 if (TREE_CODE (*node) == FUNCTION_DECL) 1164 DECL_IS_PURE (*node) = 1; 1165 /* ??? TODO: Support types. */ 1166 else 1167 { 1168 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); 1169 *no_add_attrs = true; 1170 } 1171 1172 return NULL_TREE; 1173} 1174 1175/* Handle a "deprecated" attribute; arguments as in 1176 struct attribute_spec.handler. */ 1177 1178static tree 1179handle_deprecated_attribute (node, name, args, flags, no_add_attrs) 1180 tree *node; 1181 tree name; 1182 tree args ATTRIBUTE_UNUSED; 1183 int flags; 1184 bool *no_add_attrs; 1185{ 1186 tree type = NULL_TREE; 1187 int warn = 0; 1188 const char *what = NULL; 1189 1190 if (DECL_P (*node)) 1191 { 1192 tree decl = *node; 1193 type = TREE_TYPE (decl); 1194 1195 if (TREE_CODE (decl) == TYPE_DECL 1196 || TREE_CODE (decl) == PARM_DECL 1197 || TREE_CODE (decl) == VAR_DECL 1198 || TREE_CODE (decl) == FUNCTION_DECL 1199 || TREE_CODE (decl) == FIELD_DECL) 1200 TREE_DEPRECATED (decl) = 1; 1201 else 1202 warn = 1; 1203 } 1204 else if (TYPE_P (*node)) 1205 { 1206 if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) 1207 *node = build_type_copy (*node); 1208 TREE_DEPRECATED (*node) = 1; 1209 type = *node; 1210 } 1211 else 1212 warn = 1; 1213 1214 if (warn) 1215 { 1216 *no_add_attrs = true; 1217 if (type && TYPE_NAME (type)) 1218 { 1219 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) 1220 what = IDENTIFIER_POINTER (TYPE_NAME (*node)); 1221 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL 1222 && DECL_NAME (TYPE_NAME (type))) 1223 what = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); 1224 } 1225 if (what) 1226 warning ("`%s' attribute ignored for `%s'", 1227 IDENTIFIER_POINTER (name), what); 1228 else 1229 warning ("`%s' attribute ignored", 1230 IDENTIFIER_POINTER (name)); 1231 } 1232 1233 return NULL_TREE; 1234} 1235 1236/* Handle a "vector_size" attribute; arguments as in 1237 struct attribute_spec.handler. */ 1238 1239static tree 1240handle_vector_size_attribute (node, name, args, flags, no_add_attrs) 1241 tree *node; 1242 tree name; 1243 tree args; 1244 int flags ATTRIBUTE_UNUSED; 1245 bool *no_add_attrs; 1246{ 1247 unsigned HOST_WIDE_INT vecsize, nunits; 1248 enum machine_mode mode, orig_mode, new_mode; 1249 tree type = *node, new_type; 1250 1251 *no_add_attrs = true; 1252 1253 if (! host_integerp (TREE_VALUE (args), 1)) 1254 { 1255 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); 1256 return NULL_TREE; 1257 } 1258 1259 /* Get the vector size (in bytes). */ 1260 vecsize = tree_low_cst (TREE_VALUE (args), 1); 1261 1262 /* We need to provide for vector pointers, vector arrays, and 1263 functions returning vectors. For example: 1264 1265 __attribute__((vector_size(16))) short *foo; 1266 1267 In this case, the mode is SI, but the type being modified is 1268 HI, so we need to look further. */ 1269 1270 while (POINTER_TYPE_P (type) 1271 || TREE_CODE (type) == FUNCTION_TYPE 1272 || TREE_CODE (type) == ARRAY_TYPE) 1273 type = TREE_TYPE (type); 1274 1275 /* Get the mode of the type being modified. */ 1276 orig_mode = TYPE_MODE (type); 1277 1278 if (TREE_CODE (type) == RECORD_TYPE 1279 || (GET_MODE_CLASS (orig_mode) != MODE_FLOAT 1280 && GET_MODE_CLASS (orig_mode) != MODE_INT) 1281 || ! host_integerp (TYPE_SIZE_UNIT (type), 1)) 1282 { 1283 error ("invalid vector type for attribute `%s'", 1284 IDENTIFIER_POINTER (name)); 1285 return NULL_TREE; 1286 } 1287 1288 /* Calculate how many units fit in the vector. */ 1289 nunits = vecsize / tree_low_cst (TYPE_SIZE_UNIT (type), 1); 1290 1291 /* Find a suitably sized vector. */ 1292 new_mode = VOIDmode; 1293 for (mode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (orig_mode) == MODE_INT 1294 ? MODE_VECTOR_INT 1295 : MODE_VECTOR_FLOAT); 1296 mode != VOIDmode; 1297 mode = GET_MODE_WIDER_MODE (mode)) 1298 if (vecsize == GET_MODE_SIZE (mode) 1299 && nunits == (unsigned HOST_WIDE_INT) GET_MODE_NUNITS (mode)) 1300 { 1301 new_mode = mode; 1302 break; 1303 } 1304 1305 if (new_mode == VOIDmode) 1306 error ("no vector mode with the size and type specified could be found"); 1307 else 1308 { 1309 new_type = type_for_mode (new_mode, TREE_UNSIGNED (type)); 1310 if (!new_type) 1311 error ("no vector mode with the size and type specified could be found"); 1312 else 1313 /* Build back pointers if needed. */ 1314 *node = vector_size_helper (*node, new_type); 1315 } 1316 1317 return NULL_TREE; 1318} 1319 1320/* HACK. GROSS. This is absolutely disgusting. I wish there was a 1321 better way. 1322 1323 If we requested a pointer to a vector, build up the pointers that 1324 we stripped off while looking for the inner type. Similarly for 1325 return values from functions. 1326 1327 The argument "type" is the top of the chain, and "bottom" is the 1328 new type which we will point to. */ 1329 1330static tree 1331vector_size_helper (type, bottom) 1332 tree type, bottom; 1333{ 1334 tree inner, outer; 1335 1336 if (POINTER_TYPE_P (type)) 1337 { 1338 inner = vector_size_helper (TREE_TYPE (type), bottom); 1339 outer = build_pointer_type (inner); 1340 } 1341 else if (TREE_CODE (type) == ARRAY_TYPE) 1342 { 1343 inner = vector_size_helper (TREE_TYPE (type), bottom); 1344 outer = build_array_type (inner, TYPE_VALUES (type)); 1345 } 1346 else if (TREE_CODE (type) == FUNCTION_TYPE) 1347 { 1348 inner = vector_size_helper (TREE_TYPE (type), bottom); 1349 outer = build_function_type (inner, TYPE_VALUES (type)); 1350 } 1351 else 1352 return bottom; 1353 1354 TREE_READONLY (outer) = TREE_READONLY (type); 1355 TREE_THIS_VOLATILE (outer) = TREE_THIS_VOLATILE (type); 1356 1357 return outer; 1358} 1359 1360/* Split SPECS_ATTRS, a list of declspecs and prefix attributes, into two 1361 lists. SPECS_ATTRS may also be just a typespec (eg: RECORD_TYPE). 1362 1363 The head of the declspec list is stored in DECLSPECS. 1364 The head of the attribute list is stored in PREFIX_ATTRIBUTES. 1365 1366 Note that attributes in SPECS_ATTRS are stored in the TREE_PURPOSE of 1367 the list elements. We drop the containing TREE_LIST nodes and link the 1368 resulting attributes together the way decl_attributes expects them. */ 1369 1370void 1371split_specs_attrs (specs_attrs, declspecs, prefix_attributes) 1372 tree specs_attrs; 1373 tree *declspecs, *prefix_attributes; 1374{ 1375 tree t, s, a, next, specs, attrs; 1376 1377 /* This can happen after an __extension__ in pedantic mode. */ 1378 if (specs_attrs != NULL_TREE 1379 && TREE_CODE (specs_attrs) == INTEGER_CST) 1380 { 1381 *declspecs = NULL_TREE; 1382 *prefix_attributes = NULL_TREE; 1383 return; 1384 } 1385 1386 /* This can happen in c++ (eg: decl: typespec initdecls ';'). */ 1387 if (specs_attrs != NULL_TREE 1388 && TREE_CODE (specs_attrs) != TREE_LIST) 1389 { 1390 *declspecs = specs_attrs; 1391 *prefix_attributes = NULL_TREE; 1392 return; 1393 } 1394 1395 /* Remember to keep the lists in the same order, element-wise. */ 1396 1397 specs = s = NULL_TREE; 1398 attrs = a = NULL_TREE; 1399 for (t = specs_attrs; t; t = next) 1400 { 1401 next = TREE_CHAIN (t); 1402 /* Declspecs have a non-NULL TREE_VALUE. */ 1403 if (TREE_VALUE (t) != NULL_TREE) 1404 { 1405 if (specs == NULL_TREE) 1406 specs = s = t; 1407 else 1408 { 1409 TREE_CHAIN (s) = t; 1410 s = t; 1411 } 1412 } 1413 /* The TREE_PURPOSE may also be empty in the case of 1414 __attribute__(()). */ 1415 else if (TREE_PURPOSE (t) != NULL_TREE) 1416 { 1417 if (attrs == NULL_TREE) 1418 attrs = a = TREE_PURPOSE (t); 1419 else 1420 { 1421 TREE_CHAIN (a) = TREE_PURPOSE (t); 1422 a = TREE_PURPOSE (t); 1423 } 1424 /* More attrs can be linked here, move A to the end. */ 1425 while (TREE_CHAIN (a) != NULL_TREE) 1426 a = TREE_CHAIN (a); 1427 } 1428 } 1429 1430 /* Terminate the lists. */ 1431 if (s != NULL_TREE) 1432 TREE_CHAIN (s) = NULL_TREE; 1433 if (a != NULL_TREE) 1434 TREE_CHAIN (a) = NULL_TREE; 1435 1436 /* All done. */ 1437 *declspecs = specs; 1438 *prefix_attributes = attrs; 1439} 1440 1441/* Strip attributes from SPECS_ATTRS, a list of declspecs and attributes. 1442 This function is used by the parser when a rule will accept attributes 1443 in a particular position, but we don't want to support that just yet. 1444 1445 A warning is issued for every ignored attribute. */ 1446 1447tree 1448strip_attrs (specs_attrs) 1449 tree specs_attrs; 1450{ 1451 tree specs, attrs; 1452 1453 split_specs_attrs (specs_attrs, &specs, &attrs); 1454 1455 while (attrs) 1456 { 1457 warning ("`%s' attribute ignored", 1458 IDENTIFIER_POINTER (TREE_PURPOSE (attrs))); 1459 attrs = TREE_CHAIN (attrs); 1460 } 1461 1462 return specs; 1463} 1464 1465