Mercurial > hg > CbC > CbC_gcc
annotate gcc/attribs.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
rev | line source |
---|---|
0 | 1 /* Functions dealing with attribute handling, used by most front ends. |
131 | 2 Copyright (C) 1992-2018 Free Software Foundation, Inc. |
0 | 3 |
4 This file is part of GCC. | |
5 | |
6 GCC is free software; you can redistribute it and/or modify it under | |
7 the terms of the GNU General Public License as published by the Free | |
8 Software Foundation; either version 3, or (at your option) any later | |
9 version. | |
10 | |
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
14 for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with GCC; see the file COPYING3. If not see | |
18 <http://www.gnu.org/licenses/>. */ | |
19 | |
20 #include "config.h" | |
21 #include "system.h" | |
22 #include "coretypes.h" | |
111 | 23 #include "target.h" |
0 | 24 #include "tree.h" |
111 | 25 #include "stringpool.h" |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
26 #include "diagnostic-core.h" |
111 | 27 #include "attribs.h" |
28 #include "stor-layout.h" | |
0 | 29 #include "langhooks.h" |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
30 #include "plugin.h" |
131 | 31 #include "selftest.h" |
32 #include "hash-set.h" | |
0 | 33 |
34 /* Table of the tables of attributes (common, language, format, machine) | |
35 searched. */ | |
36 static const struct attribute_spec *attribute_tables[4]; | |
37 | |
38 /* Substring representation. */ | |
39 | |
40 struct substring | |
41 { | |
42 const char *str; | |
43 int length; | |
44 }; | |
45 | |
111 | 46 /* Simple hash function to avoid need to scan whole string. */ |
47 | |
48 static inline hashval_t | |
49 substring_hash (const char *str, int l) | |
50 { | |
51 return str[0] + str[l - 1] * 256 + l * 65536; | |
52 } | |
53 | |
54 /* Used for attribute_hash. */ | |
55 | |
56 struct attribute_hasher : nofree_ptr_hash <attribute_spec> | |
57 { | |
58 typedef substring *compare_type; | |
59 static inline hashval_t hash (const attribute_spec *); | |
60 static inline bool equal (const attribute_spec *, const substring *); | |
61 }; | |
62 | |
63 inline hashval_t | |
64 attribute_hasher::hash (const attribute_spec *spec) | |
65 { | |
66 const int l = strlen (spec->name); | |
67 return substring_hash (spec->name, l); | |
68 } | |
69 | |
70 inline bool | |
71 attribute_hasher::equal (const attribute_spec *spec, const substring *str) | |
72 { | |
73 return (strncmp (spec->name, str->str, str->length) == 0 | |
74 && !spec->name[str->length]); | |
75 } | |
76 | |
77 /* Scoped attribute name representation. */ | |
78 | |
79 struct scoped_attributes | |
80 { | |
81 const char *ns; | |
82 vec<attribute_spec> attributes; | |
83 hash_table<attribute_hasher> *attribute_hash; | |
84 }; | |
85 | |
86 /* The table of scope attributes. */ | |
87 static vec<scoped_attributes> attributes_table; | |
88 | |
89 static scoped_attributes* find_attribute_namespace (const char*); | |
90 static void register_scoped_attribute (const struct attribute_spec *, | |
91 scoped_attributes *); | |
92 | |
0 | 93 static bool attributes_initialized = false; |
94 | |
95 /* Default empty table of attributes. */ | |
96 | |
97 static const struct attribute_spec empty_attribute_table[] = | |
98 { | |
131 | 99 { NULL, 0, 0, false, false, false, false, NULL, NULL } |
0 | 100 }; |
101 | |
102 /* Return base name of the attribute. Ie '__attr__' is turned into 'attr'. | |
103 To avoid need for copying, we simply return length of the string. */ | |
104 | |
105 static void | |
106 extract_attribute_substring (struct substring *str) | |
107 { | |
108 if (str->length > 4 && str->str[0] == '_' && str->str[1] == '_' | |
109 && str->str[str->length - 1] == '_' && str->str[str->length - 2] == '_') | |
110 { | |
111 str->length -= 4; | |
112 str->str += 2; | |
113 } | |
114 } | |
115 | |
111 | 116 /* Insert an array of attributes ATTRIBUTES into a namespace. This |
117 array must be NULL terminated. NS is the name of attribute | |
118 namespace. The function returns the namespace into which the | |
119 attributes have been registered. */ | |
120 | |
131 | 121 scoped_attributes * |
122 register_scoped_attributes (const struct attribute_spec *attributes, | |
123 const char *ns) | |
111 | 124 { |
125 scoped_attributes *result = NULL; | |
126 | |
127 /* See if we already have attributes in the namespace NS. */ | |
128 result = find_attribute_namespace (ns); | |
129 | |
130 if (result == NULL) | |
131 { | |
132 /* We don't have any namespace NS yet. Create one. */ | |
133 scoped_attributes sa; | |
0 | 134 |
111 | 135 if (attributes_table.is_empty ()) |
136 attributes_table.create (64); | |
137 | |
138 memset (&sa, 0, sizeof (sa)); | |
139 sa.ns = ns; | |
140 sa.attributes.create (64); | |
141 result = attributes_table.safe_push (sa); | |
142 result->attribute_hash = new hash_table<attribute_hasher> (200); | |
143 } | |
144 | |
145 /* Really add the attributes to their namespace now. */ | |
146 for (unsigned i = 0; attributes[i].name != NULL; ++i) | |
147 { | |
148 result->attributes.safe_push (attributes[i]); | |
149 register_scoped_attribute (&attributes[i], result); | |
150 } | |
151 | |
152 gcc_assert (result != NULL); | |
153 | |
154 return result; | |
0 | 155 } |
156 | |
111 | 157 /* Return the namespace which name is NS, NULL if none exist. */ |
0 | 158 |
111 | 159 static scoped_attributes* |
160 find_attribute_namespace (const char* ns) | |
0 | 161 { |
111 | 162 unsigned ix; |
163 scoped_attributes *iter; | |
0 | 164 |
111 | 165 FOR_EACH_VEC_ELT (attributes_table, ix, iter) |
166 if (ns == iter->ns | |
167 || (iter->ns != NULL | |
168 && ns != NULL | |
169 && !strcmp (iter->ns, ns))) | |
170 return iter; | |
171 return NULL; | |
0 | 172 } |
173 | |
111 | 174 /* Make some sanity checks on the attribute tables. */ |
0 | 175 |
111 | 176 static void |
177 check_attribute_tables (void) | |
0 | 178 { |
111 | 179 for (size_t i = 0; i < ARRAY_SIZE (attribute_tables); i++) |
180 for (size_t j = 0; attribute_tables[i][j].name != NULL; j++) | |
181 { | |
182 /* The name must not begin and end with __. */ | |
183 const char *name = attribute_tables[i][j].name; | |
184 int len = strlen (name); | |
185 | |
186 gcc_assert (!(name[0] == '_' && name[1] == '_' | |
187 && name[len - 1] == '_' && name[len - 2] == '_')); | |
188 | |
189 /* The minimum and maximum lengths must be consistent. */ | |
190 gcc_assert (attribute_tables[i][j].min_length >= 0); | |
191 | |
192 gcc_assert (attribute_tables[i][j].max_length == -1 | |
193 || (attribute_tables[i][j].max_length | |
194 >= attribute_tables[i][j].min_length)); | |
195 | |
196 /* An attribute cannot require both a DECL and a TYPE. */ | |
197 gcc_assert (!attribute_tables[i][j].decl_required | |
198 || !attribute_tables[i][j].type_required); | |
0 | 199 |
111 | 200 /* If an attribute requires a function type, in particular |
201 it requires a type. */ | |
202 gcc_assert (!attribute_tables[i][j].function_type_required | |
203 || attribute_tables[i][j].type_required); | |
204 } | |
205 | |
206 /* Check that each name occurs just once in each table. */ | |
207 for (size_t i = 0; i < ARRAY_SIZE (attribute_tables); i++) | |
208 for (size_t j = 0; attribute_tables[i][j].name != NULL; j++) | |
209 for (size_t k = j + 1; attribute_tables[i][k].name != NULL; k++) | |
210 gcc_assert (strcmp (attribute_tables[i][j].name, | |
211 attribute_tables[i][k].name)); | |
212 | |
213 /* Check that no name occurs in more than one table. Names that | |
214 begin with '*' are exempt, and may be overridden. */ | |
215 for (size_t i = 0; i < ARRAY_SIZE (attribute_tables); i++) | |
216 for (size_t j = i + 1; j < ARRAY_SIZE (attribute_tables); j++) | |
217 for (size_t k = 0; attribute_tables[i][k].name != NULL; k++) | |
218 for (size_t l = 0; attribute_tables[j][l].name != NULL; l++) | |
219 gcc_assert (attribute_tables[i][k].name[0] == '*' | |
220 || strcmp (attribute_tables[i][k].name, | |
221 attribute_tables[j][l].name)); | |
0 | 222 } |
223 | |
111 | 224 /* Initialize attribute tables, and make some sanity checks if checking is |
225 enabled. */ | |
0 | 226 |
111 | 227 void |
0 | 228 init_attributes (void) |
229 { | |
230 size_t i; | |
111 | 231 |
232 if (attributes_initialized) | |
233 return; | |
0 | 234 |
235 attribute_tables[0] = lang_hooks.common_attribute_table; | |
236 attribute_tables[1] = lang_hooks.attribute_table; | |
237 attribute_tables[2] = lang_hooks.format_attribute_table; | |
238 attribute_tables[3] = targetm.attribute_table; | |
239 | |
240 /* Translate NULL pointers to pointers to the empty table. */ | |
241 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++) | |
242 if (attribute_tables[i] == NULL) | |
243 attribute_tables[i] = empty_attribute_table; | |
244 | |
111 | 245 if (flag_checking) |
246 check_attribute_tables (); | |
0 | 247 |
111 | 248 for (i = 0; i < ARRAY_SIZE (attribute_tables); ++i) |
249 /* Put all the GNU attributes into the "gnu" namespace. */ | |
250 register_scoped_attributes (attribute_tables[i], "gnu"); | |
0 | 251 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
252 invoke_plugin_callbacks (PLUGIN_ATTRIBUTES, NULL); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
253 attributes_initialized = true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
254 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
255 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
256 /* Insert a single ATTR into the attribute table. */ |
0 | 257 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
258 void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
259 register_attribute (const struct attribute_spec *attr) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
260 { |
111 | 261 register_scoped_attribute (attr, find_attribute_namespace ("gnu")); |
262 } | |
263 | |
264 /* Insert a single attribute ATTR into a namespace of attributes. */ | |
265 | |
266 static void | |
267 register_scoped_attribute (const struct attribute_spec *attr, | |
268 scoped_attributes *name_space) | |
269 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
270 struct substring str; |
111 | 271 attribute_spec **slot; |
272 | |
273 gcc_assert (attr != NULL && name_space != NULL); | |
274 | |
275 gcc_assert (name_space->attribute_hash); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
276 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
277 str.str = attr->name; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
278 str.length = strlen (str.str); |
111 | 279 |
280 /* Attribute names in the table must be in the form 'text' and not | |
281 in the form '__text__'. */ | |
282 gcc_assert (str.length > 0 && str.str[0] != '_'); | |
283 | |
284 slot = name_space->attribute_hash | |
285 ->find_slot_with_hash (&str, substring_hash (str.str, str.length), | |
286 INSERT); | |
287 gcc_assert (!*slot || attr->name[0] == '*'); | |
288 *slot = CONST_CAST (struct attribute_spec *, attr); | |
0 | 289 } |
290 | |
111 | 291 /* Return the spec for the scoped attribute with namespace NS and |
292 name NAME. */ | |
293 | |
294 static const struct attribute_spec * | |
295 lookup_scoped_attribute_spec (const_tree ns, const_tree name) | |
296 { | |
297 struct substring attr; | |
298 scoped_attributes *attrs; | |
299 | |
300 const char *ns_str = (ns != NULL_TREE) ? IDENTIFIER_POINTER (ns): NULL; | |
301 | |
302 attrs = find_attribute_namespace (ns_str); | |
303 | |
304 if (attrs == NULL) | |
305 return NULL; | |
306 | |
307 attr.str = IDENTIFIER_POINTER (name); | |
308 attr.length = IDENTIFIER_LENGTH (name); | |
309 extract_attribute_substring (&attr); | |
310 return attrs->attribute_hash->find_with_hash (&attr, | |
311 substring_hash (attr.str, | |
312 attr.length)); | |
313 } | |
314 | |
315 /* Return the spec for the attribute named NAME. If NAME is a TREE_LIST, | |
316 it also specifies the attribute namespace. */ | |
0 | 317 |
318 const struct attribute_spec * | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
319 lookup_attribute_spec (const_tree name) |
0 | 320 { |
111 | 321 tree ns; |
322 if (TREE_CODE (name) == TREE_LIST) | |
323 { | |
324 ns = TREE_PURPOSE (name); | |
325 name = TREE_VALUE (name); | |
326 } | |
327 else | |
328 ns = get_identifier ("gnu"); | |
329 return lookup_scoped_attribute_spec (ns, name); | |
330 } | |
331 | |
0 | 332 |
111 | 333 /* Return the namespace of the attribute ATTR. This accessor works on |
334 GNU and C++11 (scoped) attributes. On GNU attributes, | |
335 it returns an identifier tree for the string "gnu". | |
336 | |
337 Please read the comments of cxx11_attribute_p to understand the | |
338 format of attributes. */ | |
339 | |
340 static tree | |
341 get_attribute_namespace (const_tree attr) | |
342 { | |
343 if (cxx11_attribute_p (attr)) | |
344 return TREE_PURPOSE (TREE_PURPOSE (attr)); | |
345 return get_identifier ("gnu"); | |
0 | 346 } |
111 | 347 |
131 | 348 /* Check LAST_DECL and NODE of the same symbol for attributes that are |
349 recorded in SPEC to be mutually exclusive with ATTRNAME, diagnose | |
350 them, and return true if any have been found. NODE can be a DECL | |
351 or a TYPE. */ | |
352 | |
353 static bool | |
354 diag_attr_exclusions (tree last_decl, tree node, tree attrname, | |
355 const attribute_spec *spec) | |
356 { | |
357 const attribute_spec::exclusions *excl = spec->exclude; | |
358 | |
359 tree_code code = TREE_CODE (node); | |
360 | |
361 if ((code == FUNCTION_DECL && !excl->function | |
362 && (!excl->type || !spec->affects_type_identity)) | |
363 || (code == VAR_DECL && !excl->variable | |
364 && (!excl->type || !spec->affects_type_identity)) | |
365 || (((code == TYPE_DECL || RECORD_OR_UNION_TYPE_P (node)) && !excl->type))) | |
366 return false; | |
367 | |
368 /* True if an attribute that's mutually exclusive with ATTRNAME | |
369 has been found. */ | |
370 bool found = false; | |
371 | |
372 if (last_decl && last_decl != node && TREE_TYPE (last_decl) != node) | |
373 { | |
374 /* Check both the last DECL and its type for conflicts with | |
375 the attribute being added to the current decl or type. */ | |
376 found |= diag_attr_exclusions (last_decl, last_decl, attrname, spec); | |
377 tree decl_type = TREE_TYPE (last_decl); | |
378 found |= diag_attr_exclusions (last_decl, decl_type, attrname, spec); | |
379 } | |
380 | |
381 /* NODE is either the current DECL to which the attribute is being | |
382 applied or its TYPE. For the former, consider the attributes on | |
383 both the DECL and its type. */ | |
384 tree attrs[2]; | |
385 | |
386 if (DECL_P (node)) | |
387 { | |
388 attrs[0] = DECL_ATTRIBUTES (node); | |
389 attrs[1] = TYPE_ATTRIBUTES (TREE_TYPE (node)); | |
390 } | |
391 else | |
392 { | |
393 attrs[0] = TYPE_ATTRIBUTES (node); | |
394 attrs[1] = NULL_TREE; | |
395 } | |
396 | |
397 /* Iterate over the mutually exclusive attribute names and verify | |
398 that the symbol doesn't contain it. */ | |
399 for (unsigned i = 0; i != sizeof attrs / sizeof *attrs; ++i) | |
400 { | |
401 if (!attrs[i]) | |
402 continue; | |
403 | |
404 for ( ; excl->name; ++excl) | |
405 { | |
406 /* Avoid checking the attribute against itself. */ | |
407 if (is_attribute_p (excl->name, attrname)) | |
408 continue; | |
409 | |
410 if (!lookup_attribute (excl->name, attrs[i])) | |
411 continue; | |
412 | |
413 /* An exclusion may apply either to a function declaration, | |
414 type declaration, or a field/variable declaration, or | |
415 any subset of the three. */ | |
416 if (TREE_CODE (node) == FUNCTION_DECL | |
417 && !excl->function) | |
418 continue; | |
419 | |
420 if (TREE_CODE (node) == TYPE_DECL | |
421 && !excl->type) | |
422 continue; | |
423 | |
424 if ((TREE_CODE (node) == FIELD_DECL | |
425 || TREE_CODE (node) == VAR_DECL) | |
426 && !excl->variable) | |
427 continue; | |
428 | |
429 found = true; | |
430 | |
431 /* Print a note? */ | |
432 bool note = last_decl != NULL_TREE; | |
433 auto_diagnostic_group d; | |
434 if (TREE_CODE (node) == FUNCTION_DECL | |
435 && fndecl_built_in_p (node)) | |
436 note &= warning (OPT_Wattributes, | |
437 "ignoring attribute %qE in declaration of " | |
438 "a built-in function %qD because it conflicts " | |
439 "with attribute %qs", | |
440 attrname, node, excl->name); | |
441 else | |
442 note &= warning (OPT_Wattributes, | |
443 "ignoring attribute %qE because " | |
444 "it conflicts with attribute %qs", | |
445 attrname, excl->name); | |
446 | |
447 if (note) | |
448 inform (DECL_SOURCE_LOCATION (last_decl), | |
449 "previous declaration here"); | |
450 } | |
451 } | |
452 | |
453 return found; | |
454 } | |
111 | 455 |
0 | 456 /* Process the attributes listed in ATTRIBUTES and install them in *NODE, |
457 which is either a DECL (including a TYPE_DECL) or a TYPE. If a DECL, | |
458 it should be modified in place; if a TYPE, a copy should be created | |
459 unless ATTR_FLAG_TYPE_IN_PLACE is set in FLAGS. FLAGS gives further | |
460 information, in the form of a bitwise OR of flags in enum attribute_flags | |
461 from tree.h. Depending on these flags, some attributes may be | |
462 returned to be applied at a later stage (for example, to apply | |
463 a decl attribute to the declaration rather than to its type). */ | |
464 | |
465 tree | |
131 | 466 decl_attributes (tree *node, tree attributes, int flags, |
467 tree last_decl /* = NULL_TREE */) | |
0 | 468 { |
469 tree a; | |
470 tree returned_attrs = NULL_TREE; | |
471 | |
111 | 472 if (TREE_TYPE (*node) == error_mark_node || attributes == error_mark_node) |
0 | 473 return NULL_TREE; |
474 | |
475 if (!attributes_initialized) | |
476 init_attributes (); | |
477 | |
478 /* If this is a function and the user used #pragma GCC optimize, add the | |
479 options to the attribute((optimize(...))) list. */ | |
480 if (TREE_CODE (*node) == FUNCTION_DECL && current_optimize_pragma) | |
481 { | |
482 tree cur_attr = lookup_attribute ("optimize", attributes); | |
483 tree opts = copy_list (current_optimize_pragma); | |
484 | |
485 if (! cur_attr) | |
486 attributes | |
487 = tree_cons (get_identifier ("optimize"), opts, attributes); | |
488 else | |
489 TREE_VALUE (cur_attr) = chainon (opts, TREE_VALUE (cur_attr)); | |
490 } | |
491 | |
492 if (TREE_CODE (*node) == FUNCTION_DECL | |
493 && optimization_current_node != optimization_default_node | |
494 && !DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)) | |
495 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node) = optimization_current_node; | |
496 | |
497 /* If this is a function and the user used #pragma GCC target, add the | |
498 options to the attribute((target(...))) list. */ | |
499 if (TREE_CODE (*node) == FUNCTION_DECL | |
500 && current_target_pragma | |
501 && targetm.target_option.valid_attribute_p (*node, NULL_TREE, | |
502 current_target_pragma, 0)) | |
503 { | |
504 tree cur_attr = lookup_attribute ("target", attributes); | |
505 tree opts = copy_list (current_target_pragma); | |
506 | |
507 if (! cur_attr) | |
508 attributes = tree_cons (get_identifier ("target"), opts, attributes); | |
509 else | |
510 TREE_VALUE (cur_attr) = chainon (opts, TREE_VALUE (cur_attr)); | |
511 } | |
512 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
513 /* A "naked" function attribute implies "noinline" and "noclone" for |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
514 those targets that support it. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
515 if (TREE_CODE (*node) == FUNCTION_DECL |
111 | 516 && attributes |
517 && lookup_attribute ("naked", attributes) != NULL | |
518 && lookup_attribute_spec (get_identifier ("naked"))) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
519 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
520 if (lookup_attribute ("noinline", attributes) == NULL) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
521 attributes = tree_cons (get_identifier ("noinline"), NULL, attributes); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
522 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
523 if (lookup_attribute ("noclone", attributes) == NULL) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
524 attributes = tree_cons (get_identifier ("noclone"), NULL, attributes); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
525 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
526 |
111 | 527 /* A "noipa" function attribute implies "noinline", "noclone" and "no_icf" |
528 for those targets that support it. */ | |
529 if (TREE_CODE (*node) == FUNCTION_DECL | |
530 && attributes | |
531 && lookup_attribute ("noipa", attributes) != NULL | |
532 && lookup_attribute_spec (get_identifier ("noipa"))) | |
533 { | |
534 if (lookup_attribute ("noinline", attributes) == NULL) | |
535 attributes = tree_cons (get_identifier ("noinline"), NULL, attributes); | |
536 | |
537 if (lookup_attribute ("noclone", attributes) == NULL) | |
538 attributes = tree_cons (get_identifier ("noclone"), NULL, attributes); | |
539 | |
540 if (lookup_attribute ("no_icf", attributes) == NULL) | |
541 attributes = tree_cons (get_identifier ("no_icf"), NULL, attributes); | |
542 } | |
543 | |
0 | 544 targetm.insert_attributes (*node, &attributes); |
545 | |
131 | 546 /* Note that attributes on the same declaration are not necessarily |
547 in the same order as in the source. */ | |
0 | 548 for (a = attributes; a; a = TREE_CHAIN (a)) |
549 { | |
111 | 550 tree ns = get_attribute_namespace (a); |
551 tree name = get_attribute_name (a); | |
0 | 552 tree args = TREE_VALUE (a); |
553 tree *anode = node; | |
131 | 554 const struct attribute_spec *spec |
555 = lookup_scoped_attribute_spec (ns, name); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
556 int fn_ptr_quals = 0; |
0 | 557 tree fn_ptr_tmp = NULL_TREE; |
558 | |
559 if (spec == NULL) | |
560 { | |
111 | 561 if (!(flags & (int) ATTR_FLAG_BUILT_IN)) |
562 { | |
563 if (ns == NULL_TREE || !cxx11_attribute_p (a)) | |
564 warning (OPT_Wattributes, "%qE attribute directive ignored", | |
565 name); | |
566 else | |
567 warning (OPT_Wattributes, | |
568 "%<%E::%E%> scoped attribute directive ignored", | |
569 ns, name); | |
570 } | |
0 | 571 continue; |
572 } | |
573 else if (list_length (args) < spec->min_length | |
574 || (spec->max_length >= 0 | |
575 && list_length (args) > spec->max_length)) | |
576 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
577 error ("wrong number of arguments specified for %qE attribute", |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
578 name); |
0 | 579 continue; |
580 } | |
581 gcc_assert (is_attribute_p (spec->name, name)); | |
582 | |
111 | 583 if (TYPE_P (*node) |
584 && cxx11_attribute_p (a) | |
585 && !(flags & ATTR_FLAG_TYPE_IN_PLACE)) | |
586 { | |
587 /* This is a c++11 attribute that appertains to a | |
588 type-specifier, outside of the definition of, a class | |
589 type. Ignore it. */ | |
131 | 590 auto_diagnostic_group d; |
111 | 591 if (warning (OPT_Wattributes, "attribute ignored")) |
592 inform (input_location, | |
593 "an attribute that appertains to a type-specifier " | |
594 "is ignored"); | |
595 continue; | |
596 } | |
597 | |
0 | 598 if (spec->decl_required && !DECL_P (*anode)) |
599 { | |
600 if (flags & ((int) ATTR_FLAG_DECL_NEXT | |
601 | (int) ATTR_FLAG_FUNCTION_NEXT | |
602 | (int) ATTR_FLAG_ARRAY_NEXT)) | |
603 { | |
604 /* Pass on this attribute to be tried again. */ | |
131 | 605 tree attr = tree_cons (name, args, NULL_TREE); |
606 returned_attrs = chainon (returned_attrs, attr); | |
0 | 607 continue; |
608 } | |
609 else | |
610 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
611 warning (OPT_Wattributes, "%qE attribute does not apply to types", |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
612 name); |
0 | 613 continue; |
614 } | |
615 } | |
616 | |
617 /* If we require a type, but were passed a decl, set up to make a | |
618 new type and update the one in the decl. ATTR_FLAG_TYPE_IN_PLACE | |
619 would have applied if we'd been passed a type, but we cannot modify | |
620 the decl's type in place here. */ | |
621 if (spec->type_required && DECL_P (*anode)) | |
622 { | |
623 anode = &TREE_TYPE (*anode); | |
111 | 624 flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE; |
0 | 625 } |
626 | |
627 if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE | |
628 && TREE_CODE (*anode) != METHOD_TYPE) | |
629 { | |
630 if (TREE_CODE (*anode) == POINTER_TYPE | |
631 && (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE | |
632 || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE)) | |
633 { | |
634 /* OK, this is a bit convoluted. We can't just make a copy | |
635 of the pointer type and modify its TREE_TYPE, because if | |
636 we change the attributes of the target type the pointer | |
637 type needs to have a different TYPE_MAIN_VARIANT. So we | |
638 pull out the target type now, frob it as appropriate, and | |
639 rebuild the pointer type later. | |
640 | |
641 This would all be simpler if attributes were part of the | |
642 declarator, grumble grumble. */ | |
643 fn_ptr_tmp = TREE_TYPE (*anode); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
644 fn_ptr_quals = TYPE_QUALS (*anode); |
0 | 645 anode = &fn_ptr_tmp; |
646 flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE; | |
647 } | |
648 else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT) | |
649 { | |
650 /* Pass on this attribute to be tried again. */ | |
131 | 651 tree attr = tree_cons (name, args, NULL_TREE); |
652 returned_attrs = chainon (returned_attrs, attr); | |
0 | 653 continue; |
654 } | |
655 | |
656 if (TREE_CODE (*anode) != FUNCTION_TYPE | |
657 && TREE_CODE (*anode) != METHOD_TYPE) | |
658 { | |
659 warning (OPT_Wattributes, | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
660 "%qE attribute only applies to function types", |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
661 name); |
0 | 662 continue; |
663 } | |
664 } | |
665 | |
666 if (TYPE_P (*anode) | |
667 && (flags & (int) ATTR_FLAG_TYPE_IN_PLACE) | |
668 && TYPE_SIZE (*anode) != NULL_TREE) | |
669 { | |
670 warning (OPT_Wattributes, "type attributes ignored after type is already defined"); | |
671 continue; | |
672 } | |
673 | |
131 | 674 bool no_add_attrs = false; |
675 | |
676 /* Check for exclusions with other attributes on the current | |
677 declation as well as the last declaration of the same | |
678 symbol already processed (if one exists). Detect and | |
679 reject incompatible attributes. */ | |
680 bool built_in = flags & ATTR_FLAG_BUILT_IN; | |
681 if (spec->exclude | |
682 && (flag_checking || !built_in)) | |
683 { | |
684 /* Always check attributes on user-defined functions. | |
685 Check them on built-ins only when -fchecking is set. | |
686 Ignore __builtin_unreachable -- it's both const and | |
687 noreturn. */ | |
688 | |
689 if (!built_in | |
690 || !DECL_P (*anode) | |
691 || (DECL_FUNCTION_CODE (*anode) != BUILT_IN_UNREACHABLE | |
692 && (DECL_FUNCTION_CODE (*anode) | |
693 != BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE))) | |
694 { | |
695 bool no_add = diag_attr_exclusions (last_decl, *anode, name, spec); | |
696 if (!no_add && anode != node) | |
697 no_add = diag_attr_exclusions (last_decl, *node, name, spec); | |
698 no_add_attrs |= no_add; | |
699 } | |
700 } | |
701 | |
702 if (no_add_attrs) | |
703 continue; | |
704 | |
0 | 705 if (spec->handler != NULL) |
111 | 706 { |
707 int cxx11_flag = | |
708 cxx11_attribute_p (a) ? ATTR_FLAG_CXX11 : 0; | |
709 | |
131 | 710 /* Pass in an array of the current declaration followed |
711 by the last pushed/merged declaration if one exists. | |
712 If the handler changes CUR_AND_LAST_DECL[0] replace | |
713 *ANODE with its value. */ | |
714 tree cur_and_last_decl[] = { *anode, last_decl }; | |
715 tree ret = (spec->handler) (cur_and_last_decl, name, args, | |
716 flags|cxx11_flag, &no_add_attrs); | |
717 | |
718 *anode = cur_and_last_decl[0]; | |
719 if (ret == error_mark_node) | |
720 { | |
721 warning (OPT_Wattributes, "%qE attribute ignored", name); | |
722 no_add_attrs = true; | |
723 } | |
724 else | |
725 returned_attrs = chainon (ret, returned_attrs); | |
111 | 726 } |
0 | 727 |
728 /* Layout the decl in case anything changed. */ | |
729 if (spec->type_required && DECL_P (*node) | |
111 | 730 && (VAR_P (*node) |
0 | 731 || TREE_CODE (*node) == PARM_DECL |
732 || TREE_CODE (*node) == RESULT_DECL)) | |
733 relayout_decl (*node); | |
734 | |
735 if (!no_add_attrs) | |
736 { | |
737 tree old_attrs; | |
738 tree a; | |
739 | |
740 if (DECL_P (*anode)) | |
741 old_attrs = DECL_ATTRIBUTES (*anode); | |
742 else | |
743 old_attrs = TYPE_ATTRIBUTES (*anode); | |
744 | |
745 for (a = lookup_attribute (spec->name, old_attrs); | |
746 a != NULL_TREE; | |
747 a = lookup_attribute (spec->name, TREE_CHAIN (a))) | |
748 { | |
749 if (simple_cst_equal (TREE_VALUE (a), args) == 1) | |
750 break; | |
751 } | |
752 | |
753 if (a == NULL_TREE) | |
754 { | |
755 /* This attribute isn't already in the list. */ | |
756 if (DECL_P (*anode)) | |
757 DECL_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs); | |
758 else if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE) | |
759 { | |
760 TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs); | |
761 /* If this is the main variant, also push the attributes | |
762 out to the other variants. */ | |
763 if (*anode == TYPE_MAIN_VARIANT (*anode)) | |
764 { | |
765 tree variant; | |
766 for (variant = *anode; variant; | |
767 variant = TYPE_NEXT_VARIANT (variant)) | |
768 { | |
769 if (TYPE_ATTRIBUTES (variant) == old_attrs) | |
770 TYPE_ATTRIBUTES (variant) | |
771 = TYPE_ATTRIBUTES (*anode); | |
772 else if (!lookup_attribute | |
773 (spec->name, TYPE_ATTRIBUTES (variant))) | |
774 TYPE_ATTRIBUTES (variant) = tree_cons | |
775 (name, args, TYPE_ATTRIBUTES (variant)); | |
776 } | |
777 } | |
778 } | |
779 else | |
780 *anode = build_type_attribute_variant (*anode, | |
781 tree_cons (name, args, | |
782 old_attrs)); | |
783 } | |
784 } | |
785 | |
786 if (fn_ptr_tmp) | |
787 { | |
788 /* Rebuild the function pointer type and put it in the | |
789 appropriate place. */ | |
790 fn_ptr_tmp = build_pointer_type (fn_ptr_tmp); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
791 if (fn_ptr_quals) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
792 fn_ptr_tmp = build_qualified_type (fn_ptr_tmp, fn_ptr_quals); |
0 | 793 if (DECL_P (*node)) |
794 TREE_TYPE (*node) = fn_ptr_tmp; | |
795 else | |
796 { | |
797 gcc_assert (TREE_CODE (*node) == POINTER_TYPE); | |
798 *node = fn_ptr_tmp; | |
799 } | |
800 } | |
801 } | |
802 | |
803 return returned_attrs; | |
804 } | |
111 | 805 |
806 /* Return TRUE iff ATTR has been parsed by the front-end as a C++-11 | |
807 attribute. | |
808 | |
809 When G++ parses a C++11 attribute, it is represented as | |
810 a TREE_LIST which TREE_PURPOSE is itself a TREE_LIST. TREE_PURPOSE | |
811 (TREE_PURPOSE (ATTR)) is the namespace of the attribute, and the | |
812 TREE_VALUE (TREE_PURPOSE (ATTR)) is its non-qualified name. Please | |
813 use get_attribute_namespace and get_attribute_name to retrieve the | |
814 namespace and name of the attribute, as these accessors work with | |
815 GNU attributes as well. */ | |
816 | |
817 bool | |
818 cxx11_attribute_p (const_tree attr) | |
819 { | |
820 if (attr == NULL_TREE | |
821 || TREE_CODE (attr) != TREE_LIST) | |
822 return false; | |
823 | |
824 return (TREE_CODE (TREE_PURPOSE (attr)) == TREE_LIST); | |
825 } | |
826 | |
827 /* Return the name of the attribute ATTR. This accessor works on GNU | |
828 and C++11 (scoped) attributes. | |
829 | |
830 Please read the comments of cxx11_attribute_p to understand the | |
831 format of attributes. */ | |
832 | |
833 tree | |
834 get_attribute_name (const_tree attr) | |
835 { | |
836 if (cxx11_attribute_p (attr)) | |
837 return TREE_VALUE (TREE_PURPOSE (attr)); | |
838 return TREE_PURPOSE (attr); | |
839 } | |
840 | |
841 /* Subroutine of set_method_tm_attributes. Apply TM attribute ATTR | |
842 to the method FNDECL. */ | |
843 | |
844 void | |
845 apply_tm_attr (tree fndecl, tree attr) | |
846 { | |
847 decl_attributes (&TREE_TYPE (fndecl), tree_cons (attr, NULL, NULL), 0); | |
848 } | |
849 | |
850 /* Makes a function attribute of the form NAME(ARG_NAME) and chains | |
851 it to CHAIN. */ | |
852 | |
853 tree | |
854 make_attribute (const char *name, const char *arg_name, tree chain) | |
855 { | |
856 tree attr_name; | |
857 tree attr_arg_name; | |
858 tree attr_args; | |
859 tree attr; | |
860 | |
861 attr_name = get_identifier (name); | |
862 attr_arg_name = build_string (strlen (arg_name), arg_name); | |
863 attr_args = tree_cons (NULL_TREE, attr_arg_name, NULL_TREE); | |
864 attr = tree_cons (attr_name, attr_args, chain); | |
865 return attr; | |
866 } | |
867 | |
868 | |
869 /* Common functions used for target clone support. */ | |
870 | |
871 /* Comparator function to be used in qsort routine to sort attribute | |
872 specification strings to "target". */ | |
873 | |
874 static int | |
875 attr_strcmp (const void *v1, const void *v2) | |
876 { | |
877 const char *c1 = *(char *const*)v1; | |
878 const char *c2 = *(char *const*)v2; | |
879 return strcmp (c1, c2); | |
880 } | |
881 | |
882 /* ARGLIST is the argument to target attribute. This function tokenizes | |
883 the comma separated arguments, sorts them and returns a string which | |
884 is a unique identifier for the comma separated arguments. It also | |
885 replaces non-identifier characters "=,-" with "_". */ | |
886 | |
887 char * | |
888 sorted_attr_string (tree arglist) | |
889 { | |
890 tree arg; | |
891 size_t str_len_sum = 0; | |
892 char **args = NULL; | |
893 char *attr_str, *ret_str; | |
894 char *attr = NULL; | |
895 unsigned int argnum = 1; | |
896 unsigned int i; | |
897 | |
898 for (arg = arglist; arg; arg = TREE_CHAIN (arg)) | |
899 { | |
900 const char *str = TREE_STRING_POINTER (TREE_VALUE (arg)); | |
901 size_t len = strlen (str); | |
902 str_len_sum += len + 1; | |
903 if (arg != arglist) | |
904 argnum++; | |
905 for (i = 0; i < strlen (str); i++) | |
906 if (str[i] == ',') | |
907 argnum++; | |
908 } | |
909 | |
910 attr_str = XNEWVEC (char, str_len_sum); | |
911 str_len_sum = 0; | |
912 for (arg = arglist; arg; arg = TREE_CHAIN (arg)) | |
913 { | |
914 const char *str = TREE_STRING_POINTER (TREE_VALUE (arg)); | |
915 size_t len = strlen (str); | |
916 memcpy (attr_str + str_len_sum, str, len); | |
917 attr_str[str_len_sum + len] = TREE_CHAIN (arg) ? ',' : '\0'; | |
918 str_len_sum += len + 1; | |
919 } | |
920 | |
921 /* Replace "=,-" with "_". */ | |
922 for (i = 0; i < strlen (attr_str); i++) | |
923 if (attr_str[i] == '=' || attr_str[i]== '-') | |
924 attr_str[i] = '_'; | |
925 | |
926 if (argnum == 1) | |
927 return attr_str; | |
928 | |
929 args = XNEWVEC (char *, argnum); | |
930 | |
931 i = 0; | |
932 attr = strtok (attr_str, ","); | |
933 while (attr != NULL) | |
934 { | |
935 args[i] = attr; | |
936 i++; | |
937 attr = strtok (NULL, ","); | |
938 } | |
939 | |
940 qsort (args, argnum, sizeof (char *), attr_strcmp); | |
941 | |
942 ret_str = XNEWVEC (char, str_len_sum); | |
943 str_len_sum = 0; | |
944 for (i = 0; i < argnum; i++) | |
945 { | |
946 size_t len = strlen (args[i]); | |
947 memcpy (ret_str + str_len_sum, args[i], len); | |
948 ret_str[str_len_sum + len] = i < argnum - 1 ? '_' : '\0'; | |
949 str_len_sum += len + 1; | |
950 } | |
951 | |
952 XDELETEVEC (args); | |
953 XDELETEVEC (attr_str); | |
954 return ret_str; | |
955 } | |
956 | |
957 | |
958 /* This function returns true if FN1 and FN2 are versions of the same function, | |
959 that is, the target strings of the function decls are different. This assumes | |
960 that FN1 and FN2 have the same signature. */ | |
961 | |
962 bool | |
963 common_function_versions (tree fn1, tree fn2) | |
964 { | |
965 tree attr1, attr2; | |
966 char *target1, *target2; | |
967 bool result; | |
968 | |
969 if (TREE_CODE (fn1) != FUNCTION_DECL | |
970 || TREE_CODE (fn2) != FUNCTION_DECL) | |
971 return false; | |
972 | |
973 attr1 = lookup_attribute ("target", DECL_ATTRIBUTES (fn1)); | |
974 attr2 = lookup_attribute ("target", DECL_ATTRIBUTES (fn2)); | |
975 | |
976 /* At least one function decl should have the target attribute specified. */ | |
977 if (attr1 == NULL_TREE && attr2 == NULL_TREE) | |
978 return false; | |
979 | |
980 /* Diagnose missing target attribute if one of the decls is already | |
981 multi-versioned. */ | |
982 if (attr1 == NULL_TREE || attr2 == NULL_TREE) | |
983 { | |
984 if (DECL_FUNCTION_VERSIONED (fn1) || DECL_FUNCTION_VERSIONED (fn2)) | |
985 { | |
986 if (attr2 != NULL_TREE) | |
987 { | |
988 std::swap (fn1, fn2); | |
989 attr1 = attr2; | |
990 } | |
991 error_at (DECL_SOURCE_LOCATION (fn2), | |
992 "missing %<target%> attribute for multi-versioned %qD", | |
993 fn2); | |
994 inform (DECL_SOURCE_LOCATION (fn1), | |
995 "previous declaration of %qD", fn1); | |
996 /* Prevent diagnosing of the same error multiple times. */ | |
997 DECL_ATTRIBUTES (fn2) | |
998 = tree_cons (get_identifier ("target"), | |
999 copy_node (TREE_VALUE (attr1)), | |
1000 DECL_ATTRIBUTES (fn2)); | |
1001 } | |
1002 return false; | |
1003 } | |
1004 | |
1005 target1 = sorted_attr_string (TREE_VALUE (attr1)); | |
1006 target2 = sorted_attr_string (TREE_VALUE (attr2)); | |
1007 | |
1008 /* The sorted target strings must be different for fn1 and fn2 | |
1009 to be versions. */ | |
1010 if (strcmp (target1, target2) == 0) | |
1011 result = false; | |
1012 else | |
1013 result = true; | |
1014 | |
1015 XDELETEVEC (target1); | |
1016 XDELETEVEC (target2); | |
1017 | |
1018 return result; | |
1019 } | |
1020 | |
1021 /* Return a new name by appending SUFFIX to the DECL name. If make_unique | |
1022 is true, append the full path name of the source file. */ | |
1023 | |
1024 char * | |
1025 make_unique_name (tree decl, const char *suffix, bool make_unique) | |
1026 { | |
1027 char *global_var_name; | |
1028 int name_len; | |
1029 const char *name; | |
1030 const char *unique_name = NULL; | |
1031 | |
1032 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); | |
1033 | |
1034 /* Get a unique name that can be used globally without any chances | |
1035 of collision at link time. */ | |
1036 if (make_unique) | |
1037 unique_name = IDENTIFIER_POINTER (get_file_function_name ("\0")); | |
1038 | |
1039 name_len = strlen (name) + strlen (suffix) + 2; | |
1040 | |
1041 if (make_unique) | |
1042 name_len += strlen (unique_name) + 1; | |
1043 global_var_name = XNEWVEC (char, name_len); | |
1044 | |
1045 /* Use '.' to concatenate names as it is demangler friendly. */ | |
1046 if (make_unique) | |
1047 snprintf (global_var_name, name_len, "%s.%s.%s", name, unique_name, | |
1048 suffix); | |
1049 else | |
1050 snprintf (global_var_name, name_len, "%s.%s", name, suffix); | |
1051 | |
1052 return global_var_name; | |
1053 } | |
1054 | |
1055 /* Make a dispatcher declaration for the multi-versioned function DECL. | |
1056 Calls to DECL function will be replaced with calls to the dispatcher | |
1057 by the front-end. Return the decl created. */ | |
1058 | |
1059 tree | |
1060 make_dispatcher_decl (const tree decl) | |
1061 { | |
1062 tree func_decl; | |
1063 char *func_name; | |
1064 tree fn_type, func_type; | |
1065 | |
1066 func_name = xstrdup (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); | |
1067 | |
1068 fn_type = TREE_TYPE (decl); | |
1069 func_type = build_function_type (TREE_TYPE (fn_type), | |
1070 TYPE_ARG_TYPES (fn_type)); | |
1071 | |
1072 func_decl = build_fn_decl (func_name, func_type); | |
1073 XDELETEVEC (func_name); | |
1074 TREE_USED (func_decl) = 1; | |
1075 DECL_CONTEXT (func_decl) = NULL_TREE; | |
1076 DECL_INITIAL (func_decl) = error_mark_node; | |
1077 DECL_ARTIFICIAL (func_decl) = 1; | |
1078 /* Mark this func as external, the resolver will flip it again if | |
1079 it gets generated. */ | |
1080 DECL_EXTERNAL (func_decl) = 1; | |
1081 /* This will be of type IFUNCs have to be externally visible. */ | |
1082 TREE_PUBLIC (func_decl) = 1; | |
1083 | |
1084 return func_decl; | |
1085 } | |
1086 | |
1087 /* Returns true if decl is multi-versioned and DECL is the default function, | |
1088 that is it is not tagged with target specific optimization. */ | |
1089 | |
1090 bool | |
1091 is_function_default_version (const tree decl) | |
1092 { | |
1093 if (TREE_CODE (decl) != FUNCTION_DECL | |
1094 || !DECL_FUNCTION_VERSIONED (decl)) | |
1095 return false; | |
1096 tree attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl)); | |
1097 gcc_assert (attr); | |
1098 attr = TREE_VALUE (TREE_VALUE (attr)); | |
1099 return (TREE_CODE (attr) == STRING_CST | |
1100 && strcmp (TREE_STRING_POINTER (attr), "default") == 0); | |
1101 } | |
1102 | |
1103 /* Return a declaration like DDECL except that its DECL_ATTRIBUTES | |
1104 is ATTRIBUTE. */ | |
1105 | |
1106 tree | |
1107 build_decl_attribute_variant (tree ddecl, tree attribute) | |
1108 { | |
1109 DECL_ATTRIBUTES (ddecl) = attribute; | |
1110 return ddecl; | |
1111 } | |
1112 | |
1113 /* Return a type like TTYPE except that its TYPE_ATTRIBUTE | |
1114 is ATTRIBUTE and its qualifiers are QUALS. | |
1115 | |
1116 Record such modified types already made so we don't make duplicates. */ | |
1117 | |
1118 tree | |
1119 build_type_attribute_qual_variant (tree otype, tree attribute, int quals) | |
1120 { | |
1121 tree ttype = otype; | |
1122 if (! attribute_list_equal (TYPE_ATTRIBUTES (ttype), attribute)) | |
1123 { | |
1124 tree ntype; | |
1125 | |
1126 /* Building a distinct copy of a tagged type is inappropriate; it | |
1127 causes breakage in code that expects there to be a one-to-one | |
1128 relationship between a struct and its fields. | |
1129 build_duplicate_type is another solution (as used in | |
1130 handle_transparent_union_attribute), but that doesn't play well | |
1131 with the stronger C++ type identity model. */ | |
1132 if (TREE_CODE (ttype) == RECORD_TYPE | |
1133 || TREE_CODE (ttype) == UNION_TYPE | |
1134 || TREE_CODE (ttype) == QUAL_UNION_TYPE | |
1135 || TREE_CODE (ttype) == ENUMERAL_TYPE) | |
1136 { | |
1137 warning (OPT_Wattributes, | |
1138 "ignoring attributes applied to %qT after definition", | |
1139 TYPE_MAIN_VARIANT (ttype)); | |
1140 return build_qualified_type (ttype, quals); | |
1141 } | |
1142 | |
1143 ttype = build_qualified_type (ttype, TYPE_UNQUALIFIED); | |
1144 if (lang_hooks.types.copy_lang_qualifiers | |
1145 && otype != TYPE_MAIN_VARIANT (otype)) | |
1146 ttype = (lang_hooks.types.copy_lang_qualifiers | |
1147 (ttype, TYPE_MAIN_VARIANT (otype))); | |
1148 | |
131 | 1149 tree dtype = ntype = build_distinct_type_copy (ttype); |
111 | 1150 |
1151 TYPE_ATTRIBUTES (ntype) = attribute; | |
1152 | |
1153 hashval_t hash = type_hash_canon_hash (ntype); | |
1154 ntype = type_hash_canon (hash, ntype); | |
1155 | |
131 | 1156 if (ntype != dtype) |
1157 /* This variant was already in the hash table, don't mess with | |
1158 TYPE_CANONICAL. */; | |
1159 else if (TYPE_STRUCTURAL_EQUALITY_P (ttype) | |
1160 || !comp_type_attributes (ntype, ttype)) | |
1161 /* If the target-dependent attributes make NTYPE different from | |
1162 its canonical type, we will need to use structural equality | |
1163 checks for this type. | |
1164 | |
1165 We shouldn't get here for stripping attributes from a type; | |
1166 the no-attribute type might not need structural comparison. But | |
1167 we can if was discarded from type_hash_table. */ | |
111 | 1168 SET_TYPE_STRUCTURAL_EQUALITY (ntype); |
1169 else if (TYPE_CANONICAL (ntype) == ntype) | |
1170 TYPE_CANONICAL (ntype) = TYPE_CANONICAL (ttype); | |
1171 | |
1172 ttype = build_qualified_type (ntype, quals); | |
1173 if (lang_hooks.types.copy_lang_qualifiers | |
1174 && otype != TYPE_MAIN_VARIANT (otype)) | |
1175 ttype = lang_hooks.types.copy_lang_qualifiers (ttype, otype); | |
1176 } | |
1177 else if (TYPE_QUALS (ttype) != quals) | |
1178 ttype = build_qualified_type (ttype, quals); | |
1179 | |
1180 return ttype; | |
1181 } | |
1182 | |
1183 /* Compare two identifier nodes representing attributes. | |
1184 Return true if they are the same, false otherwise. */ | |
1185 | |
1186 static bool | |
1187 cmp_attrib_identifiers (const_tree attr1, const_tree attr2) | |
1188 { | |
1189 /* Make sure we're dealing with IDENTIFIER_NODEs. */ | |
1190 gcc_checking_assert (TREE_CODE (attr1) == IDENTIFIER_NODE | |
1191 && TREE_CODE (attr2) == IDENTIFIER_NODE); | |
1192 | |
1193 /* Identifiers can be compared directly for equality. */ | |
1194 if (attr1 == attr2) | |
1195 return true; | |
1196 | |
1197 return cmp_attribs (IDENTIFIER_POINTER (attr1), IDENTIFIER_LENGTH (attr1), | |
1198 IDENTIFIER_POINTER (attr2), IDENTIFIER_LENGTH (attr2)); | |
1199 } | |
1200 | |
1201 /* Compare two constructor-element-type constants. Return 1 if the lists | |
1202 are known to be equal; otherwise return 0. */ | |
1203 | |
1204 static bool | |
1205 simple_cst_list_equal (const_tree l1, const_tree l2) | |
1206 { | |
1207 while (l1 != NULL_TREE && l2 != NULL_TREE) | |
1208 { | |
1209 if (simple_cst_equal (TREE_VALUE (l1), TREE_VALUE (l2)) != 1) | |
1210 return false; | |
1211 | |
1212 l1 = TREE_CHAIN (l1); | |
1213 l2 = TREE_CHAIN (l2); | |
1214 } | |
1215 | |
1216 return l1 == l2; | |
1217 } | |
1218 | |
1219 /* Check if "omp declare simd" attribute arguments, CLAUSES1 and CLAUSES2, are | |
1220 the same. */ | |
1221 | |
1222 static bool | |
1223 omp_declare_simd_clauses_equal (tree clauses1, tree clauses2) | |
1224 { | |
1225 tree cl1, cl2; | |
1226 for (cl1 = clauses1, cl2 = clauses2; | |
1227 cl1 && cl2; | |
1228 cl1 = OMP_CLAUSE_CHAIN (cl1), cl2 = OMP_CLAUSE_CHAIN (cl2)) | |
1229 { | |
1230 if (OMP_CLAUSE_CODE (cl1) != OMP_CLAUSE_CODE (cl2)) | |
1231 return false; | |
1232 if (OMP_CLAUSE_CODE (cl1) != OMP_CLAUSE_SIMDLEN) | |
1233 { | |
1234 if (simple_cst_equal (OMP_CLAUSE_DECL (cl1), | |
1235 OMP_CLAUSE_DECL (cl2)) != 1) | |
1236 return false; | |
1237 } | |
1238 switch (OMP_CLAUSE_CODE (cl1)) | |
1239 { | |
1240 case OMP_CLAUSE_ALIGNED: | |
1241 if (simple_cst_equal (OMP_CLAUSE_ALIGNED_ALIGNMENT (cl1), | |
1242 OMP_CLAUSE_ALIGNED_ALIGNMENT (cl2)) != 1) | |
1243 return false; | |
1244 break; | |
1245 case OMP_CLAUSE_LINEAR: | |
1246 if (simple_cst_equal (OMP_CLAUSE_LINEAR_STEP (cl1), | |
1247 OMP_CLAUSE_LINEAR_STEP (cl2)) != 1) | |
1248 return false; | |
1249 break; | |
1250 case OMP_CLAUSE_SIMDLEN: | |
1251 if (simple_cst_equal (OMP_CLAUSE_SIMDLEN_EXPR (cl1), | |
1252 OMP_CLAUSE_SIMDLEN_EXPR (cl2)) != 1) | |
1253 return false; | |
1254 default: | |
1255 break; | |
1256 } | |
1257 } | |
1258 return true; | |
1259 } | |
1260 | |
1261 | |
1262 /* Compare two attributes for their value identity. Return true if the | |
1263 attribute values are known to be equal; otherwise return false. */ | |
1264 | |
1265 bool | |
1266 attribute_value_equal (const_tree attr1, const_tree attr2) | |
1267 { | |
1268 if (TREE_VALUE (attr1) == TREE_VALUE (attr2)) | |
1269 return true; | |
1270 | |
1271 if (TREE_VALUE (attr1) != NULL_TREE | |
1272 && TREE_CODE (TREE_VALUE (attr1)) == TREE_LIST | |
1273 && TREE_VALUE (attr2) != NULL_TREE | |
1274 && TREE_CODE (TREE_VALUE (attr2)) == TREE_LIST) | |
1275 { | |
1276 /* Handle attribute format. */ | |
1277 if (is_attribute_p ("format", get_attribute_name (attr1))) | |
1278 { | |
1279 attr1 = TREE_VALUE (attr1); | |
1280 attr2 = TREE_VALUE (attr2); | |
1281 /* Compare the archetypes (printf/scanf/strftime/...). */ | |
1282 if (!cmp_attrib_identifiers (TREE_VALUE (attr1), TREE_VALUE (attr2))) | |
1283 return false; | |
1284 /* Archetypes are the same. Compare the rest. */ | |
1285 return (simple_cst_list_equal (TREE_CHAIN (attr1), | |
1286 TREE_CHAIN (attr2)) == 1); | |
1287 } | |
1288 return (simple_cst_list_equal (TREE_VALUE (attr1), | |
1289 TREE_VALUE (attr2)) == 1); | |
1290 } | |
1291 | |
1292 if (TREE_VALUE (attr1) | |
1293 && TREE_CODE (TREE_VALUE (attr1)) == OMP_CLAUSE | |
1294 && TREE_VALUE (attr2) | |
1295 && TREE_CODE (TREE_VALUE (attr2)) == OMP_CLAUSE) | |
1296 return omp_declare_simd_clauses_equal (TREE_VALUE (attr1), | |
1297 TREE_VALUE (attr2)); | |
1298 | |
1299 return (simple_cst_equal (TREE_VALUE (attr1), TREE_VALUE (attr2)) == 1); | |
1300 } | |
1301 | |
1302 /* Return 0 if the attributes for two types are incompatible, 1 if they | |
1303 are compatible, and 2 if they are nearly compatible (which causes a | |
1304 warning to be generated). */ | |
1305 int | |
1306 comp_type_attributes (const_tree type1, const_tree type2) | |
1307 { | |
1308 const_tree a1 = TYPE_ATTRIBUTES (type1); | |
1309 const_tree a2 = TYPE_ATTRIBUTES (type2); | |
1310 const_tree a; | |
1311 | |
1312 if (a1 == a2) | |
1313 return 1; | |
1314 for (a = a1; a != NULL_TREE; a = TREE_CHAIN (a)) | |
1315 { | |
1316 const struct attribute_spec *as; | |
1317 const_tree attr; | |
1318 | |
1319 as = lookup_attribute_spec (get_attribute_name (a)); | |
1320 if (!as || as->affects_type_identity == false) | |
1321 continue; | |
1322 | |
1323 attr = lookup_attribute (as->name, CONST_CAST_TREE (a2)); | |
1324 if (!attr || !attribute_value_equal (a, attr)) | |
1325 break; | |
1326 } | |
1327 if (!a) | |
1328 { | |
1329 for (a = a2; a != NULL_TREE; a = TREE_CHAIN (a)) | |
1330 { | |
1331 const struct attribute_spec *as; | |
1332 | |
1333 as = lookup_attribute_spec (get_attribute_name (a)); | |
1334 if (!as || as->affects_type_identity == false) | |
1335 continue; | |
1336 | |
1337 if (!lookup_attribute (as->name, CONST_CAST_TREE (a1))) | |
1338 break; | |
1339 /* We don't need to compare trees again, as we did this | |
1340 already in first loop. */ | |
1341 } | |
1342 /* All types - affecting identity - are equal, so | |
1343 there is no need to call target hook for comparison. */ | |
1344 if (!a) | |
1345 return 1; | |
1346 } | |
1347 if (lookup_attribute ("transaction_safe", CONST_CAST_TREE (a))) | |
1348 return 0; | |
1349 if ((lookup_attribute ("nocf_check", TYPE_ATTRIBUTES (type1)) != NULL) | |
1350 ^ (lookup_attribute ("nocf_check", TYPE_ATTRIBUTES (type2)) != NULL)) | |
1351 return 0; | |
1352 /* As some type combinations - like default calling-convention - might | |
1353 be compatible, we have to call the target hook to get the final result. */ | |
1354 return targetm.comp_type_attributes (type1, type2); | |
1355 } | |
1356 | |
1357 /* Return a type like TTYPE except that its TYPE_ATTRIBUTE | |
1358 is ATTRIBUTE. | |
1359 | |
1360 Record such modified types already made so we don't make duplicates. */ | |
1361 | |
1362 tree | |
1363 build_type_attribute_variant (tree ttype, tree attribute) | |
1364 { | |
1365 return build_type_attribute_qual_variant (ttype, attribute, | |
1366 TYPE_QUALS (ttype)); | |
1367 } | |
1368 | |
1369 /* A variant of lookup_attribute() that can be used with an identifier | |
1370 as the first argument, and where the identifier can be either | |
1371 'text' or '__text__'. | |
1372 | |
1373 Given an attribute ATTR_IDENTIFIER, and a list of attributes LIST, | |
1374 return a pointer to the attribute's list element if the attribute | |
1375 is part of the list, or NULL_TREE if not found. If the attribute | |
1376 appears more than once, this only returns the first occurrence; the | |
1377 TREE_CHAIN of the return value should be passed back in if further | |
1378 occurrences are wanted. ATTR_IDENTIFIER must be an identifier but | |
1379 can be in the form 'text' or '__text__'. */ | |
1380 static tree | |
1381 lookup_ident_attribute (tree attr_identifier, tree list) | |
1382 { | |
1383 gcc_checking_assert (TREE_CODE (attr_identifier) == IDENTIFIER_NODE); | |
1384 | |
1385 while (list) | |
1386 { | |
1387 gcc_checking_assert (TREE_CODE (get_attribute_name (list)) | |
1388 == IDENTIFIER_NODE); | |
1389 | |
1390 if (cmp_attrib_identifiers (attr_identifier, | |
1391 get_attribute_name (list))) | |
1392 /* Found it. */ | |
1393 break; | |
1394 list = TREE_CHAIN (list); | |
1395 } | |
1396 | |
1397 return list; | |
1398 } | |
1399 | |
1400 /* Remove any instances of attribute ATTR_NAME in LIST and return the | |
1401 modified list. */ | |
1402 | |
1403 tree | |
1404 remove_attribute (const char *attr_name, tree list) | |
1405 { | |
1406 tree *p; | |
1407 gcc_checking_assert (attr_name[0] != '_'); | |
1408 | |
1409 for (p = &list; *p;) | |
1410 { | |
1411 tree l = *p; | |
1412 | |
1413 tree attr = get_attribute_name (l); | |
1414 if (is_attribute_p (attr_name, attr)) | |
1415 *p = TREE_CHAIN (l); | |
1416 else | |
1417 p = &TREE_CHAIN (l); | |
1418 } | |
1419 | |
1420 return list; | |
1421 } | |
1422 | |
1423 /* Return an attribute list that is the union of a1 and a2. */ | |
1424 | |
1425 tree | |
1426 merge_attributes (tree a1, tree a2) | |
1427 { | |
1428 tree attributes; | |
1429 | |
1430 /* Either one unset? Take the set one. */ | |
1431 | |
1432 if ((attributes = a1) == 0) | |
1433 attributes = a2; | |
1434 | |
1435 /* One that completely contains the other? Take it. */ | |
1436 | |
1437 else if (a2 != 0 && ! attribute_list_contained (a1, a2)) | |
1438 { | |
1439 if (attribute_list_contained (a2, a1)) | |
1440 attributes = a2; | |
1441 else | |
1442 { | |
1443 /* Pick the longest list, and hang on the other list. */ | |
1444 | |
1445 if (list_length (a1) < list_length (a2)) | |
1446 attributes = a2, a2 = a1; | |
1447 | |
1448 for (; a2 != 0; a2 = TREE_CHAIN (a2)) | |
1449 { | |
1450 tree a; | |
1451 for (a = lookup_ident_attribute (get_attribute_name (a2), | |
1452 attributes); | |
1453 a != NULL_TREE && !attribute_value_equal (a, a2); | |
1454 a = lookup_ident_attribute (get_attribute_name (a2), | |
1455 TREE_CHAIN (a))) | |
1456 ; | |
1457 if (a == NULL_TREE) | |
1458 { | |
1459 a1 = copy_node (a2); | |
1460 TREE_CHAIN (a1) = attributes; | |
1461 attributes = a1; | |
1462 } | |
1463 } | |
1464 } | |
1465 } | |
1466 return attributes; | |
1467 } | |
1468 | |
1469 /* Given types T1 and T2, merge their attributes and return | |
1470 the result. */ | |
1471 | |
1472 tree | |
1473 merge_type_attributes (tree t1, tree t2) | |
1474 { | |
1475 return merge_attributes (TYPE_ATTRIBUTES (t1), | |
1476 TYPE_ATTRIBUTES (t2)); | |
1477 } | |
1478 | |
1479 /* Given decls OLDDECL and NEWDECL, merge their attributes and return | |
1480 the result. */ | |
1481 | |
1482 tree | |
1483 merge_decl_attributes (tree olddecl, tree newdecl) | |
1484 { | |
1485 return merge_attributes (DECL_ATTRIBUTES (olddecl), | |
1486 DECL_ATTRIBUTES (newdecl)); | |
1487 } | |
1488 | |
1489 /* Duplicate all attributes with name NAME in ATTR list to *ATTRS if | |
1490 they are missing there. */ | |
1491 | |
1492 void | |
1493 duplicate_one_attribute (tree *attrs, tree attr, const char *name) | |
1494 { | |
1495 attr = lookup_attribute (name, attr); | |
1496 if (!attr) | |
1497 return; | |
1498 tree a = lookup_attribute (name, *attrs); | |
1499 while (attr) | |
1500 { | |
1501 tree a2; | |
1502 for (a2 = a; a2; a2 = lookup_attribute (name, TREE_CHAIN (a2))) | |
1503 if (attribute_value_equal (attr, a2)) | |
1504 break; | |
1505 if (!a2) | |
1506 { | |
1507 a2 = copy_node (attr); | |
1508 TREE_CHAIN (a2) = *attrs; | |
1509 *attrs = a2; | |
1510 } | |
1511 attr = lookup_attribute (name, TREE_CHAIN (attr)); | |
1512 } | |
1513 } | |
1514 | |
1515 /* Duplicate all attributes from user DECL to the corresponding | |
1516 builtin that should be propagated. */ | |
1517 | |
1518 void | |
1519 copy_attributes_to_builtin (tree decl) | |
1520 { | |
1521 tree b = builtin_decl_explicit (DECL_FUNCTION_CODE (decl)); | |
1522 if (b) | |
1523 duplicate_one_attribute (&DECL_ATTRIBUTES (b), | |
1524 DECL_ATTRIBUTES (decl), "omp declare simd"); | |
1525 } | |
1526 | |
1527 #if TARGET_DLLIMPORT_DECL_ATTRIBUTES | |
1528 | |
1529 /* Specialization of merge_decl_attributes for various Windows targets. | |
1530 | |
1531 This handles the following situation: | |
1532 | |
1533 __declspec (dllimport) int foo; | |
1534 int foo; | |
1535 | |
1536 The second instance of `foo' nullifies the dllimport. */ | |
1537 | |
1538 tree | |
1539 merge_dllimport_decl_attributes (tree old, tree new_tree) | |
1540 { | |
1541 tree a; | |
1542 int delete_dllimport_p = 1; | |
1543 | |
1544 /* What we need to do here is remove from `old' dllimport if it doesn't | |
1545 appear in `new'. dllimport behaves like extern: if a declaration is | |
1546 marked dllimport and a definition appears later, then the object | |
1547 is not dllimport'd. We also remove a `new' dllimport if the old list | |
1548 contains dllexport: dllexport always overrides dllimport, regardless | |
1549 of the order of declaration. */ | |
1550 if (!VAR_OR_FUNCTION_DECL_P (new_tree)) | |
1551 delete_dllimport_p = 0; | |
1552 else if (DECL_DLLIMPORT_P (new_tree) | |
1553 && lookup_attribute ("dllexport", DECL_ATTRIBUTES (old))) | |
1554 { | |
1555 DECL_DLLIMPORT_P (new_tree) = 0; | |
1556 warning (OPT_Wattributes, "%q+D already declared with dllexport " | |
1557 "attribute: dllimport ignored", new_tree); | |
1558 } | |
1559 else if (DECL_DLLIMPORT_P (old) && !DECL_DLLIMPORT_P (new_tree)) | |
1560 { | |
1561 /* Warn about overriding a symbol that has already been used, e.g.: | |
1562 extern int __attribute__ ((dllimport)) foo; | |
1563 int* bar () {return &foo;} | |
1564 int foo; | |
1565 */ | |
1566 if (TREE_USED (old)) | |
1567 { | |
1568 warning (0, "%q+D redeclared without dllimport attribute " | |
1569 "after being referenced with dll linkage", new_tree); | |
1570 /* If we have used a variable's address with dllimport linkage, | |
1571 keep the old DECL_DLLIMPORT_P flag: the ADDR_EXPR using the | |
1572 decl may already have had TREE_CONSTANT computed. | |
1573 We still remove the attribute so that assembler code refers | |
1574 to '&foo rather than '_imp__foo'. */ | |
1575 if (VAR_P (old) && TREE_ADDRESSABLE (old)) | |
1576 DECL_DLLIMPORT_P (new_tree) = 1; | |
1577 } | |
1578 | |
1579 /* Let an inline definition silently override the external reference, | |
1580 but otherwise warn about attribute inconsistency. */ | |
1581 else if (VAR_P (new_tree) || !DECL_DECLARED_INLINE_P (new_tree)) | |
1582 warning (OPT_Wattributes, "%q+D redeclared without dllimport " | |
1583 "attribute: previous dllimport ignored", new_tree); | |
1584 } | |
1585 else | |
1586 delete_dllimport_p = 0; | |
1587 | |
1588 a = merge_attributes (DECL_ATTRIBUTES (old), DECL_ATTRIBUTES (new_tree)); | |
1589 | |
1590 if (delete_dllimport_p) | |
1591 a = remove_attribute ("dllimport", a); | |
1592 | |
1593 return a; | |
1594 } | |
1595 | |
1596 /* Handle a "dllimport" or "dllexport" attribute; arguments as in | |
1597 struct attribute_spec.handler. */ | |
1598 | |
1599 tree | |
1600 handle_dll_attribute (tree * pnode, tree name, tree args, int flags, | |
1601 bool *no_add_attrs) | |
1602 { | |
1603 tree node = *pnode; | |
1604 bool is_dllimport; | |
1605 | |
1606 /* These attributes may apply to structure and union types being created, | |
1607 but otherwise should pass to the declaration involved. */ | |
1608 if (!DECL_P (node)) | |
1609 { | |
1610 if (flags & ((int) ATTR_FLAG_DECL_NEXT | (int) ATTR_FLAG_FUNCTION_NEXT | |
1611 | (int) ATTR_FLAG_ARRAY_NEXT)) | |
1612 { | |
1613 *no_add_attrs = true; | |
1614 return tree_cons (name, args, NULL_TREE); | |
1615 } | |
1616 if (TREE_CODE (node) == RECORD_TYPE | |
1617 || TREE_CODE (node) == UNION_TYPE) | |
1618 { | |
1619 node = TYPE_NAME (node); | |
1620 if (!node) | |
1621 return NULL_TREE; | |
1622 } | |
1623 else | |
1624 { | |
1625 warning (OPT_Wattributes, "%qE attribute ignored", | |
1626 name); | |
1627 *no_add_attrs = true; | |
1628 return NULL_TREE; | |
1629 } | |
1630 } | |
1631 | |
1632 if (!VAR_OR_FUNCTION_DECL_P (node) && TREE_CODE (node) != TYPE_DECL) | |
1633 { | |
1634 *no_add_attrs = true; | |
1635 warning (OPT_Wattributes, "%qE attribute ignored", | |
1636 name); | |
1637 return NULL_TREE; | |
1638 } | |
1639 | |
1640 if (TREE_CODE (node) == TYPE_DECL | |
1641 && TREE_CODE (TREE_TYPE (node)) != RECORD_TYPE | |
1642 && TREE_CODE (TREE_TYPE (node)) != UNION_TYPE) | |
1643 { | |
1644 *no_add_attrs = true; | |
1645 warning (OPT_Wattributes, "%qE attribute ignored", | |
1646 name); | |
1647 return NULL_TREE; | |
1648 } | |
1649 | |
1650 is_dllimport = is_attribute_p ("dllimport", name); | |
1651 | |
1652 /* Report error on dllimport ambiguities seen now before they cause | |
1653 any damage. */ | |
1654 if (is_dllimport) | |
1655 { | |
1656 /* Honor any target-specific overrides. */ | |
1657 if (!targetm.valid_dllimport_attribute_p (node)) | |
1658 *no_add_attrs = true; | |
1659 | |
1660 else if (TREE_CODE (node) == FUNCTION_DECL | |
1661 && DECL_DECLARED_INLINE_P (node)) | |
1662 { | |
1663 warning (OPT_Wattributes, "inline function %q+D declared as " | |
1664 " dllimport: attribute ignored", node); | |
1665 *no_add_attrs = true; | |
1666 } | |
1667 /* Like MS, treat definition of dllimported variables and | |
1668 non-inlined functions on declaration as syntax errors. */ | |
1669 else if (TREE_CODE (node) == FUNCTION_DECL && DECL_INITIAL (node)) | |
1670 { | |
1671 error ("function %q+D definition is marked dllimport", node); | |
1672 *no_add_attrs = true; | |
1673 } | |
1674 | |
1675 else if (VAR_P (node)) | |
1676 { | |
1677 if (DECL_INITIAL (node)) | |
1678 { | |
1679 error ("variable %q+D definition is marked dllimport", | |
1680 node); | |
1681 *no_add_attrs = true; | |
1682 } | |
1683 | |
1684 /* `extern' needn't be specified with dllimport. | |
1685 Specify `extern' now and hope for the best. Sigh. */ | |
1686 DECL_EXTERNAL (node) = 1; | |
1687 /* Also, implicitly give dllimport'd variables declared within | |
1688 a function global scope, unless declared static. */ | |
1689 if (current_function_decl != NULL_TREE && !TREE_STATIC (node)) | |
1690 TREE_PUBLIC (node) = 1; | |
1691 } | |
1692 | |
1693 if (*no_add_attrs == false) | |
1694 DECL_DLLIMPORT_P (node) = 1; | |
1695 } | |
1696 else if (TREE_CODE (node) == FUNCTION_DECL | |
1697 && DECL_DECLARED_INLINE_P (node) | |
1698 && flag_keep_inline_dllexport) | |
1699 /* An exported function, even if inline, must be emitted. */ | |
1700 DECL_EXTERNAL (node) = 0; | |
1701 | |
1702 /* Report error if symbol is not accessible at global scope. */ | |
1703 if (!TREE_PUBLIC (node) && VAR_OR_FUNCTION_DECL_P (node)) | |
1704 { | |
1705 error ("external linkage required for symbol %q+D because of " | |
1706 "%qE attribute", node, name); | |
1707 *no_add_attrs = true; | |
1708 } | |
1709 | |
1710 /* A dllexport'd entity must have default visibility so that other | |
1711 program units (shared libraries or the main executable) can see | |
1712 it. A dllimport'd entity must have default visibility so that | |
1713 the linker knows that undefined references within this program | |
1714 unit can be resolved by the dynamic linker. */ | |
1715 if (!*no_add_attrs) | |
1716 { | |
1717 if (DECL_VISIBILITY_SPECIFIED (node) | |
1718 && DECL_VISIBILITY (node) != VISIBILITY_DEFAULT) | |
1719 error ("%qE implies default visibility, but %qD has already " | |
1720 "been declared with a different visibility", | |
1721 name, node); | |
1722 DECL_VISIBILITY (node) = VISIBILITY_DEFAULT; | |
1723 DECL_VISIBILITY_SPECIFIED (node) = 1; | |
1724 } | |
1725 | |
1726 return NULL_TREE; | |
1727 } | |
1728 | |
1729 #endif /* TARGET_DLLIMPORT_DECL_ATTRIBUTES */ | |
1730 | |
1731 /* Given two lists of attributes, return true if list l2 is | |
1732 equivalent to l1. */ | |
1733 | |
1734 int | |
1735 attribute_list_equal (const_tree l1, const_tree l2) | |
1736 { | |
1737 if (l1 == l2) | |
1738 return 1; | |
1739 | |
1740 return attribute_list_contained (l1, l2) | |
1741 && attribute_list_contained (l2, l1); | |
1742 } | |
1743 | |
1744 /* Given two lists of attributes, return true if list L2 is | |
1745 completely contained within L1. */ | |
1746 /* ??? This would be faster if attribute names were stored in a canonicalized | |
1747 form. Otherwise, if L1 uses `foo' and L2 uses `__foo__', the long method | |
1748 must be used to show these elements are equivalent (which they are). */ | |
1749 /* ??? It's not clear that attributes with arguments will always be handled | |
1750 correctly. */ | |
1751 | |
1752 int | |
1753 attribute_list_contained (const_tree l1, const_tree l2) | |
1754 { | |
1755 const_tree t1, t2; | |
1756 | |
1757 /* First check the obvious, maybe the lists are identical. */ | |
1758 if (l1 == l2) | |
1759 return 1; | |
1760 | |
1761 /* Maybe the lists are similar. */ | |
1762 for (t1 = l1, t2 = l2; | |
1763 t1 != 0 && t2 != 0 | |
1764 && get_attribute_name (t1) == get_attribute_name (t2) | |
1765 && TREE_VALUE (t1) == TREE_VALUE (t2); | |
1766 t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2)) | |
1767 ; | |
1768 | |
1769 /* Maybe the lists are equal. */ | |
1770 if (t1 == 0 && t2 == 0) | |
1771 return 1; | |
1772 | |
1773 for (; t2 != 0; t2 = TREE_CHAIN (t2)) | |
1774 { | |
1775 const_tree attr; | |
1776 /* This CONST_CAST is okay because lookup_attribute does not | |
1777 modify its argument and the return value is assigned to a | |
1778 const_tree. */ | |
1779 for (attr = lookup_ident_attribute (get_attribute_name (t2), | |
1780 CONST_CAST_TREE (l1)); | |
1781 attr != NULL_TREE && !attribute_value_equal (t2, attr); | |
1782 attr = lookup_ident_attribute (get_attribute_name (t2), | |
1783 TREE_CHAIN (attr))) | |
1784 ; | |
1785 | |
1786 if (attr == NULL_TREE) | |
1787 return 0; | |
1788 } | |
1789 | |
1790 return 1; | |
1791 } | |
1792 | |
1793 /* The backbone of lookup_attribute(). ATTR_LEN is the string length | |
1794 of ATTR_NAME, and LIST is not NULL_TREE. | |
1795 | |
1796 The function is called from lookup_attribute in order to optimize | |
1797 for size. */ | |
1798 | |
1799 tree | |
1800 private_lookup_attribute (const char *attr_name, size_t attr_len, tree list) | |
1801 { | |
1802 while (list) | |
1803 { | |
1804 tree attr = get_attribute_name (list); | |
1805 size_t ident_len = IDENTIFIER_LENGTH (attr); | |
1806 if (cmp_attribs (attr_name, attr_len, IDENTIFIER_POINTER (attr), | |
1807 ident_len)) | |
1808 break; | |
1809 list = TREE_CHAIN (list); | |
1810 } | |
1811 | |
1812 return list; | |
1813 } | |
131 | 1814 |
1815 #if CHECKING_P | |
1816 | |
1817 namespace selftest | |
1818 { | |
1819 | |
1820 /* Helper types to verify the consistency attribute exclusions. */ | |
1821 | |
1822 typedef std::pair<const char *, const char *> excl_pair; | |
1823 | |
1824 struct excl_hash_traits: typed_noop_remove<excl_pair> | |
1825 { | |
1826 typedef excl_pair value_type; | |
1827 typedef value_type compare_type; | |
1828 | |
1829 static hashval_t hash (const value_type &x) | |
1830 { | |
1831 hashval_t h1 = htab_hash_string (x.first); | |
1832 hashval_t h2 = htab_hash_string (x.second); | |
1833 return h1 ^ h2; | |
1834 } | |
1835 | |
1836 static bool equal (const value_type &x, const value_type &y) | |
1837 { | |
1838 return !strcmp (x.first, y.first) && !strcmp (x.second, y.second); | |
1839 } | |
1840 | |
1841 static void mark_deleted (value_type &x) | |
1842 { | |
1843 x = value_type (NULL, NULL); | |
1844 } | |
1845 | |
1846 static void mark_empty (value_type &x) | |
1847 { | |
1848 x = value_type ("", ""); | |
1849 } | |
1850 | |
1851 static bool is_deleted (const value_type &x) | |
1852 { | |
1853 return !x.first && !x.second; | |
1854 } | |
1855 | |
1856 static bool is_empty (const value_type &x) | |
1857 { | |
1858 return !*x.first && !*x.second; | |
1859 } | |
1860 }; | |
1861 | |
1862 | |
1863 /* Self-test to verify that each attribute exclusion is symmetric, | |
1864 meaning that if attribute A is encoded as incompatible with | |
1865 attribute B then the opposite relationship is also encoded. | |
1866 This test also detects most cases of misspelled attribute names | |
1867 in exclusions. */ | |
1868 | |
1869 static void | |
1870 test_attribute_exclusions () | |
1871 { | |
1872 /* Iterate over the array of attribute tables first (with TI0 as | |
1873 the index) and over the array of attribute_spec in each table | |
1874 (with SI0 as the index). */ | |
1875 const size_t ntables = ARRAY_SIZE (attribute_tables); | |
1876 | |
1877 /* Set of pairs of mutually exclusive attributes. */ | |
1878 typedef hash_set<excl_pair, excl_hash_traits> exclusion_set; | |
1879 exclusion_set excl_set; | |
1880 | |
1881 for (size_t ti0 = 0; ti0 != ntables; ++ti0) | |
1882 for (size_t s0 = 0; attribute_tables[ti0][s0].name; ++s0) | |
1883 { | |
1884 const attribute_spec::exclusions *excl | |
1885 = attribute_tables[ti0][s0].exclude; | |
1886 | |
1887 /* Skip each attribute that doesn't define exclusions. */ | |
1888 if (!excl) | |
1889 continue; | |
1890 | |
1891 const char *attr_name = attribute_tables[ti0][s0].name; | |
1892 | |
1893 /* Iterate over the set of exclusions for every attribute | |
1894 (with EI0 as the index) adding the exclusions defined | |
1895 for each to the set. */ | |
1896 for (size_t ei0 = 0; excl[ei0].name; ++ei0) | |
1897 { | |
1898 const char *excl_name = excl[ei0].name; | |
1899 | |
1900 if (!strcmp (attr_name, excl_name)) | |
1901 continue; | |
1902 | |
1903 excl_set.add (excl_pair (attr_name, excl_name)); | |
1904 } | |
1905 } | |
1906 | |
1907 /* Traverse the set of mutually exclusive pairs of attributes | |
1908 and verify that they are symmetric. */ | |
1909 for (exclusion_set::iterator it = excl_set.begin (); | |
1910 it != excl_set.end (); | |
1911 ++it) | |
1912 { | |
1913 if (!excl_set.contains (excl_pair ((*it).second, (*it).first))) | |
1914 { | |
1915 /* An exclusion for an attribute has been found that | |
1916 doesn't have a corresponding exclusion in the opposite | |
1917 direction. */ | |
1918 char desc[120]; | |
1919 sprintf (desc, "'%s' attribute exclusion '%s' must be symmetric", | |
1920 (*it).first, (*it).second); | |
1921 fail (SELFTEST_LOCATION, desc); | |
1922 } | |
1923 } | |
1924 } | |
1925 | |
1926 void | |
1927 attribute_c_tests () | |
1928 { | |
1929 test_attribute_exclusions (); | |
1930 } | |
1931 | |
1932 } /* namespace selftest */ | |
1933 | |
1934 #endif /* CHECKING_P */ |