attribs.c revision 146895
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, 2003 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 "coretypes.h" 25#include "tm.h" 26#include "tree.h" 27#include "flags.h" 28#include "toplev.h" 29#include "output.h" 30#include "rtl.h" 31#include "ggc.h" 32#include "expr.h" 33#include "tm_p.h" 34#include "cpplib.h" 35#include "target.h" 36#include "langhooks.h" 37 38static void init_attributes (void); 39 40/* Table of the tables of attributes (common, language, format, machine) 41 searched. */ 42static const struct attribute_spec *attribute_tables[4]; 43 44static bool attributes_initialized = false; 45 46/* Default empty table of attributes. */ 47static const struct attribute_spec empty_attribute_table[] = 48{ 49 { NULL, 0, 0, false, false, false, NULL } 50}; 51 52/* Initialize attribute tables, and make some sanity checks 53 if --enable-checking. */ 54 55static void 56init_attributes (void) 57{ 58 size_t i; 59 60 attribute_tables[0] = lang_hooks.common_attribute_table; 61 attribute_tables[1] = lang_hooks.attribute_table; 62 attribute_tables[2] = lang_hooks.format_attribute_table; 63 attribute_tables[3] = targetm.attribute_table; 64 65 /* Translate NULL pointers to pointers to the empty table. */ 66 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++) 67 if (attribute_tables[i] == NULL) 68 attribute_tables[i] = empty_attribute_table; 69 70#ifdef ENABLE_CHECKING 71 /* Make some sanity checks on the attribute tables. */ 72 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++) 73 { 74 int j; 75 76 for (j = 0; attribute_tables[i][j].name != NULL; j++) 77 { 78 /* The name must not begin and end with __. */ 79 const char *name = attribute_tables[i][j].name; 80 int len = strlen (name); 81 if (name[0] == '_' && name[1] == '_' 82 && name[len - 1] == '_' && name[len - 2] == '_') 83 abort (); 84 /* The minimum and maximum lengths must be consistent. */ 85 if (attribute_tables[i][j].min_length < 0) 86 abort (); 87 if (attribute_tables[i][j].max_length != -1 88 && (attribute_tables[i][j].max_length 89 < attribute_tables[i][j].min_length)) 90 abort (); 91 /* An attribute cannot require both a DECL and a TYPE. */ 92 if (attribute_tables[i][j].decl_required 93 && attribute_tables[i][j].type_required) 94 abort (); 95 /* If an attribute requires a function type, in particular 96 it requires a type. */ 97 if (attribute_tables[i][j].function_type_required 98 && !attribute_tables[i][j].type_required) 99 abort (); 100 } 101 } 102 103 /* Check that each name occurs just once in each table. */ 104 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++) 105 { 106 int j, k; 107 for (j = 0; attribute_tables[i][j].name != NULL; j++) 108 for (k = j + 1; attribute_tables[i][k].name != NULL; k++) 109 if (!strcmp (attribute_tables[i][j].name, 110 attribute_tables[i][k].name)) 111 abort (); 112 } 113 /* Check that no name occurs in more than one table. */ 114 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++) 115 { 116 size_t j, k, l; 117 118 for (j = i + 1; j < ARRAY_SIZE (attribute_tables); j++) 119 for (k = 0; attribute_tables[i][k].name != NULL; k++) 120 for (l = 0; attribute_tables[j][l].name != NULL; l++) 121 if (!strcmp (attribute_tables[i][k].name, 122 attribute_tables[j][l].name)) 123 abort (); 124 } 125#endif 126 127 attributes_initialized = true; 128} 129 130/* Process the attributes listed in ATTRIBUTES and install them in *NODE, 131 which is either a DECL (including a TYPE_DECL) or a TYPE. If a DECL, 132 it should be modified in place; if a TYPE, a copy should be created 133 unless ATTR_FLAG_TYPE_IN_PLACE is set in FLAGS. FLAGS gives further 134 information, in the form of a bitwise OR of flags in enum attribute_flags 135 from tree.h. Depending on these flags, some attributes may be 136 returned to be applied at a later stage (for example, to apply 137 a decl attribute to the declaration rather than to its type). */ 138 139tree 140decl_attributes (tree *node, tree attributes, int flags) 141{ 142 tree a; 143 tree returned_attrs = NULL_TREE; 144 145 if (!attributes_initialized) 146 init_attributes (); 147 148 (*targetm.insert_attributes) (*node, &attributes); 149 150 for (a = attributes; a; a = TREE_CHAIN (a)) 151 { 152 tree name = TREE_PURPOSE (a); 153 tree args = TREE_VALUE (a); 154 tree *anode = node; 155 const struct attribute_spec *spec = NULL; 156 bool no_add_attrs = 0; 157 tree fn_ptr_tmp = NULL_TREE; 158 size_t i; 159 160 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++) 161 { 162 int j; 163 164 for (j = 0; attribute_tables[i][j].name != NULL; j++) 165 { 166 if (is_attribute_p (attribute_tables[i][j].name, name)) 167 { 168 spec = &attribute_tables[i][j]; 169 break; 170 } 171 } 172 if (spec != NULL) 173 break; 174 } 175 176 if (spec == NULL) 177 { 178 warning ("`%s' attribute directive ignored", 179 IDENTIFIER_POINTER (name)); 180 continue; 181 } 182 else if (list_length (args) < spec->min_length 183 || (spec->max_length >= 0 184 && list_length (args) > spec->max_length)) 185 { 186 error ("wrong number of arguments specified for `%s' attribute", 187 IDENTIFIER_POINTER (name)); 188 continue; 189 } 190 191 if (spec->decl_required && !DECL_P (*anode)) 192 { 193 if (flags & ((int) ATTR_FLAG_DECL_NEXT 194 | (int) ATTR_FLAG_FUNCTION_NEXT 195 | (int) ATTR_FLAG_ARRAY_NEXT)) 196 { 197 /* Pass on this attribute to be tried again. */ 198 returned_attrs = tree_cons (name, args, returned_attrs); 199 continue; 200 } 201 else 202 { 203 warning ("`%s' attribute does not apply to types", 204 IDENTIFIER_POINTER (name)); 205 continue; 206 } 207 } 208 209 /* If we require a type, but were passed a decl, set up to make a 210 new type and update the one in the decl. ATTR_FLAG_TYPE_IN_PLACE 211 would have applied if we'd been passed a type, but we cannot modify 212 the decl's type in place here. */ 213 if (spec->type_required && DECL_P (*anode)) 214 { 215 anode = &TREE_TYPE (*anode); 216 flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE; 217 } 218 219 if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE 220 && TREE_CODE (*anode) != METHOD_TYPE) 221 { 222 if (TREE_CODE (*anode) == POINTER_TYPE 223 && (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE 224 || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE)) 225 { 226 /* OK, this is a bit convoluted. We can't just make a copy 227 of the pointer type and modify its TREE_TYPE, because if 228 we change the attributes of the target type the pointer 229 type needs to have a different TYPE_MAIN_VARIANT. So we 230 pull out the target type now, frob it as appropriate, and 231 rebuild the pointer type later. 232 233 This would all be simpler if attributes were part of the 234 declarator, grumble grumble. */ 235 fn_ptr_tmp = TREE_TYPE (*anode); 236 anode = &fn_ptr_tmp; 237 flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE; 238 } 239 else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT) 240 { 241 /* Pass on this attribute to be tried again. */ 242 returned_attrs = tree_cons (name, args, returned_attrs); 243 continue; 244 } 245 246 if (TREE_CODE (*anode) != FUNCTION_TYPE 247 && TREE_CODE (*anode) != METHOD_TYPE) 248 { 249 warning ("`%s' attribute only applies to function types", 250 IDENTIFIER_POINTER (name)); 251 continue; 252 } 253 } 254 255 if (spec->handler != NULL) 256 returned_attrs = chainon ((*spec->handler) (anode, name, args, 257 flags, &no_add_attrs), 258 returned_attrs); 259 260 /* Layout the decl in case anything changed. */ 261 if (spec->type_required && DECL_P (*node) 262 && (TREE_CODE (*node) == VAR_DECL 263 || TREE_CODE (*node) == PARM_DECL 264 || TREE_CODE (*node) == RESULT_DECL)) 265 { 266 /* Force a recalculation of mode and size. */ 267 DECL_MODE (*node) = VOIDmode; 268 DECL_SIZE (*node) = 0; 269 if (!DECL_USER_ALIGN (*node)) 270 DECL_ALIGN (*node) = 0; 271 272 layout_decl (*node, 0); 273 } 274 275 if (!no_add_attrs) 276 { 277 tree old_attrs; 278 tree a; 279 280 if (DECL_P (*anode)) 281 old_attrs = DECL_ATTRIBUTES (*anode); 282 else 283 old_attrs = TYPE_ATTRIBUTES (*anode); 284 285 for (a = lookup_attribute (spec->name, old_attrs); 286 a != NULL_TREE; 287 a = lookup_attribute (spec->name, TREE_CHAIN (a))) 288 { 289 if (simple_cst_equal (TREE_VALUE (a), args) == 1) 290 break; 291 } 292 293 if (a == NULL_TREE) 294 { 295 /* This attribute isn't already in the list. */ 296 if (DECL_P (*anode)) 297 DECL_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs); 298 else if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE) 299 TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs); 300 else 301 *anode = build_type_attribute_variant (*anode, 302 tree_cons (name, args, 303 old_attrs)); 304 } 305 } 306 307 if (fn_ptr_tmp) 308 { 309 /* Rebuild the function pointer type and put it in the 310 appropriate place. */ 311 fn_ptr_tmp = build_pointer_type (fn_ptr_tmp); 312 if (DECL_P (*node)) 313 TREE_TYPE (*node) = fn_ptr_tmp; 314 else if (TREE_CODE (*node) == POINTER_TYPE) 315 *node = fn_ptr_tmp; 316 else 317 abort (); 318 } 319 } 320 321 return returned_attrs; 322} 323 324/* Split SPECS_ATTRS, a list of declspecs and prefix attributes, into two 325 lists. SPECS_ATTRS may also be just a typespec (eg: RECORD_TYPE). 326 327 The head of the declspec list is stored in DECLSPECS. 328 The head of the attribute list is stored in PREFIX_ATTRIBUTES. 329 330 Note that attributes in SPECS_ATTRS are stored in the TREE_PURPOSE of 331 the list elements. We drop the containing TREE_LIST nodes and link the 332 resulting attributes together the way decl_attributes expects them. */ 333 334void 335split_specs_attrs (tree specs_attrs, tree *declspecs, tree *prefix_attributes) 336{ 337 tree t, s, a, next, specs, attrs; 338 339 /* This can happen after an __extension__ in pedantic mode. */ 340 if (specs_attrs != NULL_TREE 341 && TREE_CODE (specs_attrs) == INTEGER_CST) 342 { 343 *declspecs = NULL_TREE; 344 *prefix_attributes = NULL_TREE; 345 return; 346 } 347 348 /* This can happen in c++ (eg: decl: typespec initdecls ';'). */ 349 if (specs_attrs != NULL_TREE 350 && TREE_CODE (specs_attrs) != TREE_LIST) 351 { 352 *declspecs = specs_attrs; 353 *prefix_attributes = NULL_TREE; 354 return; 355 } 356 357 /* Remember to keep the lists in the same order, element-wise. */ 358 359 specs = s = NULL_TREE; 360 attrs = a = NULL_TREE; 361 for (t = specs_attrs; t; t = next) 362 { 363 next = TREE_CHAIN (t); 364 /* Declspecs have a non-NULL TREE_VALUE. */ 365 if (TREE_VALUE (t) != NULL_TREE) 366 { 367 if (specs == NULL_TREE) 368 specs = s = t; 369 else 370 { 371 TREE_CHAIN (s) = t; 372 s = t; 373 } 374 } 375 /* The TREE_PURPOSE may also be empty in the case of 376 __attribute__(()). */ 377 else if (TREE_PURPOSE (t) != NULL_TREE) 378 { 379 if (attrs == NULL_TREE) 380 attrs = a = TREE_PURPOSE (t); 381 else 382 { 383 TREE_CHAIN (a) = TREE_PURPOSE (t); 384 a = TREE_PURPOSE (t); 385 } 386 /* More attrs can be linked here, move A to the end. */ 387 while (TREE_CHAIN (a) != NULL_TREE) 388 a = TREE_CHAIN (a); 389 } 390 } 391 392 /* Terminate the lists. */ 393 if (s != NULL_TREE) 394 TREE_CHAIN (s) = NULL_TREE; 395 if (a != NULL_TREE) 396 TREE_CHAIN (a) = NULL_TREE; 397 398 /* All done. */ 399 *declspecs = specs; 400 *prefix_attributes = attrs; 401} 402 403/* Strip attributes from SPECS_ATTRS, a list of declspecs and attributes. 404 This function is used by the parser when a rule will accept attributes 405 in a particular position, but we don't want to support that just yet. 406 407 A warning is issued for every ignored attribute. */ 408 409tree 410strip_attrs (tree specs_attrs) 411{ 412 tree specs, attrs; 413 414 split_specs_attrs (specs_attrs, &specs, &attrs); 415 416 while (attrs) 417 { 418 warning ("`%s' attribute ignored", 419 IDENTIFIER_POINTER (TREE_PURPOSE (attrs))); 420 attrs = TREE_CHAIN (attrs); 421 } 422 423 return specs; 424} 425