OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [attribs.c] - Blame information for rev 867

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 684 jeremybenn
/* 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, 2004, 2005, 2007, 2008, 2009, 2010
4
   Free Software Foundation, Inc.
5
 
6
This file is part of GCC.
7
 
8
GCC is free software; you can redistribute it and/or modify it under
9
the terms of the GNU General Public License as published by the Free
10
Software Foundation; either version 3, or (at your option) any later
11
version.
12
 
13
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14
WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16
for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with GCC; see the file COPYING3.  If not see
20
<http://www.gnu.org/licenses/>.  */
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 "diagnostic-core.h"
29
#include "ggc.h"
30
#include "tm_p.h"
31
#include "cpplib.h"
32
#include "target.h"
33
#include "langhooks.h"
34
#include "hashtab.h"
35
#include "plugin.h"
36
 
37
/* Table of the tables of attributes (common, language, format, machine)
38
   searched.  */
39
static const struct attribute_spec *attribute_tables[4];
40
 
41
/* Hashtable mapping names (represented as substrings) to attribute specs. */
42
static htab_t attribute_hash;
43
 
44
/* Substring representation.  */
45
 
46
struct substring
47
{
48
  const char *str;
49
  int length;
50
};
51
 
52
static bool attributes_initialized = false;
53
 
54
/* Default empty table of attributes.  */
55
 
56
static const struct attribute_spec empty_attribute_table[] =
57
{
58
  { NULL, 0, 0, false, false, false, NULL, false }
59
};
60
 
61
/* Return base name of the attribute.  Ie '__attr__' is turned into 'attr'.
62
   To avoid need for copying, we simply return length of the string.  */
63
 
64
static void
65
extract_attribute_substring (struct substring *str)
66
{
67
  if (str->length > 4 && str->str[0] == '_' && str->str[1] == '_'
68
      && str->str[str->length - 1] == '_' && str->str[str->length - 2] == '_')
69
    {
70
      str->length -= 4;
71
      str->str += 2;
72
    }
73
}
74
 
75
/* Simple hash function to avoid need to scan whole string.  */
76
 
77
static inline hashval_t
78
substring_hash (const char *str, int l)
79
{
80
  return str[0] + str[l - 1] * 256 + l * 65536;
81
}
82
 
83
/* Used for attribute_hash.  */
84
 
85
static hashval_t
86
hash_attr (const void *p)
87
{
88
  const struct attribute_spec *const spec = (const struct attribute_spec *) p;
89
  const int l = strlen (spec->name);
90
 
91
  return substring_hash (spec->name, l);
92
}
93
 
94
/* Used for attribute_hash.  */
95
 
96
static int
97
eq_attr (const void *p, const void *q)
98
{
99
  const struct attribute_spec *const spec = (const struct attribute_spec *) p;
100
  const struct substring *const str = (const struct substring *) q;
101
 
102
  return (!strncmp (spec->name, str->str, str->length) && !spec->name[str->length]);
103
}
104
 
105
/* Initialize attribute tables, and make some sanity checks
106
   if --enable-checking.  */
107
 
108
void
109
init_attributes (void)
110
{
111
  size_t i;
112
  int k;
113
 
114
  if (attributes_initialized)
115
    return;
116
 
117
  attribute_tables[0] = lang_hooks.common_attribute_table;
118
  attribute_tables[1] = lang_hooks.attribute_table;
119
  attribute_tables[2] = lang_hooks.format_attribute_table;
120
  attribute_tables[3] = targetm.attribute_table;
121
 
122
  /* Translate NULL pointers to pointers to the empty table.  */
123
  for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
124
    if (attribute_tables[i] == NULL)
125
      attribute_tables[i] = empty_attribute_table;
126
 
127
#ifdef ENABLE_CHECKING
128
  /* Make some sanity checks on the attribute tables.  */
129
  for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
130
    {
131
      int j;
132
 
133
      for (j = 0; attribute_tables[i][j].name != NULL; j++)
134
        {
135
          /* The name must not begin and end with __.  */
136
          const char *name = attribute_tables[i][j].name;
137
          int len = strlen (name);
138
 
139
          gcc_assert (!(name[0] == '_' && name[1] == '_'
140
                        && name[len - 1] == '_' && name[len - 2] == '_'));
141
 
142
          /* The minimum and maximum lengths must be consistent.  */
143
          gcc_assert (attribute_tables[i][j].min_length >= 0);
144
 
145
          gcc_assert (attribute_tables[i][j].max_length == -1
146
                      || (attribute_tables[i][j].max_length
147
                          >= attribute_tables[i][j].min_length));
148
 
149
          /* An attribute cannot require both a DECL and a TYPE.  */
150
          gcc_assert (!attribute_tables[i][j].decl_required
151
                      || !attribute_tables[i][j].type_required);
152
 
153
          /* If an attribute requires a function type, in particular
154
             it requires a type.  */
155
          gcc_assert (!attribute_tables[i][j].function_type_required
156
                      || attribute_tables[i][j].type_required);
157
        }
158
    }
159
 
160
  /* Check that each name occurs just once in each table.  */
161
  for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
162
    {
163
      int j, k;
164
      for (j = 0; attribute_tables[i][j].name != NULL; j++)
165
        for (k = j + 1; attribute_tables[i][k].name != NULL; k++)
166
          gcc_assert (strcmp (attribute_tables[i][j].name,
167
                              attribute_tables[i][k].name));
168
    }
169
  /* Check that no name occurs in more than one table.  Names that
170
     begin with '*' are exempt, and may be overridden.  */
171
  for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
172
    {
173
      size_t j, k, l;
174
 
175
      for (j = i + 1; j < ARRAY_SIZE (attribute_tables); j++)
176
        for (k = 0; attribute_tables[i][k].name != NULL; k++)
177
          for (l = 0; attribute_tables[j][l].name != NULL; l++)
178
            gcc_assert (attribute_tables[i][k].name[0] == '*'
179
                        || strcmp (attribute_tables[i][k].name,
180
                                   attribute_tables[j][l].name));
181
    }
182
#endif
183
 
184
  attribute_hash = htab_create (200, hash_attr, eq_attr, NULL);
185
  for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
186
    for (k = 0; attribute_tables[i][k].name != NULL; k++)
187
      {
188
        register_attribute (&attribute_tables[i][k]);
189
      }
190
  invoke_plugin_callbacks (PLUGIN_ATTRIBUTES, NULL);
191
  attributes_initialized = true;
192
}
193
 
194
/* Insert a single ATTR into the attribute table.  */
195
 
196
void
197
register_attribute (const struct attribute_spec *attr)
198
{
199
  struct substring str;
200
  void **slot;
201
 
202
  str.str = attr->name;
203
  str.length = strlen (str.str);
204
 
205
  /* Attribute names in the table must be in the form 'text' and not
206
     in the form '__text__'.  */
207
  gcc_assert (str.length > 0 && str.str[0] != '_');
208
 
209
  slot = htab_find_slot_with_hash (attribute_hash, &str,
210
                                   substring_hash (str.str, str.length),
211
                                   INSERT);
212
  gcc_assert (!*slot || attr->name[0] == '*');
213
  *slot = (void *) CONST_CAST (struct attribute_spec *, attr);
214
}
215
 
216
/* Return the spec for the attribute named NAME.  */
217
 
218
const struct attribute_spec *
219
lookup_attribute_spec (const_tree name)
220
{
221
  struct substring attr;
222
 
223
  attr.str = IDENTIFIER_POINTER (name);
224
  attr.length = IDENTIFIER_LENGTH (name);
225
  extract_attribute_substring (&attr);
226
  return (const struct attribute_spec *)
227
    htab_find_with_hash (attribute_hash, &attr,
228
                         substring_hash (attr.str, attr.length));
229
}
230
 
231
/* Process the attributes listed in ATTRIBUTES and install them in *NODE,
232
   which is either a DECL (including a TYPE_DECL) or a TYPE.  If a DECL,
233
   it should be modified in place; if a TYPE, a copy should be created
234
   unless ATTR_FLAG_TYPE_IN_PLACE is set in FLAGS.  FLAGS gives further
235
   information, in the form of a bitwise OR of flags in enum attribute_flags
236
   from tree.h.  Depending on these flags, some attributes may be
237
   returned to be applied at a later stage (for example, to apply
238
   a decl attribute to the declaration rather than to its type).  */
239
 
240
tree
241
decl_attributes (tree *node, tree attributes, int flags)
242
{
243
  tree a;
244
  tree returned_attrs = NULL_TREE;
245
 
246
  if (TREE_TYPE (*node) == error_mark_node)
247
    return NULL_TREE;
248
 
249
  if (!attributes_initialized)
250
    init_attributes ();
251
 
252
  /* If this is a function and the user used #pragma GCC optimize, add the
253
     options to the attribute((optimize(...))) list.  */
254
  if (TREE_CODE (*node) == FUNCTION_DECL && current_optimize_pragma)
255
    {
256
      tree cur_attr = lookup_attribute ("optimize", attributes);
257
      tree opts = copy_list (current_optimize_pragma);
258
 
259
      if (! cur_attr)
260
        attributes
261
          = tree_cons (get_identifier ("optimize"), opts, attributes);
262
      else
263
        TREE_VALUE (cur_attr) = chainon (opts, TREE_VALUE (cur_attr));
264
    }
265
 
266
  if (TREE_CODE (*node) == FUNCTION_DECL
267
      && optimization_current_node != optimization_default_node
268
      && !DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node))
269
    DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node) = optimization_current_node;
270
 
271
  /* If this is a function and the user used #pragma GCC target, add the
272
     options to the attribute((target(...))) list.  */
273
  if (TREE_CODE (*node) == FUNCTION_DECL
274
      && current_target_pragma
275
      && targetm.target_option.valid_attribute_p (*node, NULL_TREE,
276
                                                  current_target_pragma, 0))
277
    {
278
      tree cur_attr = lookup_attribute ("target", attributes);
279
      tree opts = copy_list (current_target_pragma);
280
 
281
      if (! cur_attr)
282
        attributes = tree_cons (get_identifier ("target"), opts, attributes);
283
      else
284
        TREE_VALUE (cur_attr) = chainon (opts, TREE_VALUE (cur_attr));
285
    }
286
 
287
  /* A "naked" function attribute implies "noinline" and "noclone" for
288
     those targets that support it.  */
289
  if (TREE_CODE (*node) == FUNCTION_DECL
290
      && attributes
291
      && lookup_attribute_spec (get_identifier ("naked"))
292
      && lookup_attribute ("naked", attributes) != NULL)
293
    {
294
      if (lookup_attribute ("noinline", attributes) == NULL)
295
        attributes = tree_cons (get_identifier ("noinline"), NULL, attributes);
296
 
297
      if (lookup_attribute ("noclone", attributes) == NULL)
298
        attributes = tree_cons (get_identifier ("noclone"),  NULL, attributes);
299
    }
300
 
301
  targetm.insert_attributes (*node, &attributes);
302
 
303
  for (a = attributes; a; a = TREE_CHAIN (a))
304
    {
305
      tree name = TREE_PURPOSE (a);
306
      tree args = TREE_VALUE (a);
307
      tree *anode = node;
308
      const struct attribute_spec *spec = lookup_attribute_spec (name);
309
      bool no_add_attrs = 0;
310
      int fn_ptr_quals = 0;
311
      tree fn_ptr_tmp = NULL_TREE;
312
 
313
      if (spec == NULL)
314
        {
315
          warning (OPT_Wattributes, "%qE attribute directive ignored",
316
                   name);
317
          continue;
318
        }
319
      else if (list_length (args) < spec->min_length
320
               || (spec->max_length >= 0
321
                   && list_length (args) > spec->max_length))
322
        {
323
          error ("wrong number of arguments specified for %qE attribute",
324
                 name);
325
          continue;
326
        }
327
      gcc_assert (is_attribute_p (spec->name, name));
328
 
329
      if (spec->decl_required && !DECL_P (*anode))
330
        {
331
          if (flags & ((int) ATTR_FLAG_DECL_NEXT
332
                       | (int) ATTR_FLAG_FUNCTION_NEXT
333
                       | (int) ATTR_FLAG_ARRAY_NEXT))
334
            {
335
              /* Pass on this attribute to be tried again.  */
336
              returned_attrs = tree_cons (name, args, returned_attrs);
337
              continue;
338
            }
339
          else
340
            {
341
              warning (OPT_Wattributes, "%qE attribute does not apply to types",
342
                       name);
343
              continue;
344
            }
345
        }
346
 
347
      /* If we require a type, but were passed a decl, set up to make a
348
         new type and update the one in the decl.  ATTR_FLAG_TYPE_IN_PLACE
349
         would have applied if we'd been passed a type, but we cannot modify
350
         the decl's type in place here.  */
351
      if (spec->type_required && DECL_P (*anode))
352
        {
353
          anode = &TREE_TYPE (*anode);
354
          /* Allow ATTR_FLAG_TYPE_IN_PLACE for the type's naming decl.  */
355
          if (!(TREE_CODE (*anode) == TYPE_DECL
356
                && *anode == TYPE_NAME (TYPE_MAIN_VARIANT
357
                                        (TREE_TYPE (*anode)))))
358
            flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
359
        }
360
 
361
      if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE
362
          && TREE_CODE (*anode) != METHOD_TYPE)
363
        {
364
          if (TREE_CODE (*anode) == POINTER_TYPE
365
              && (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE
366
                  || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE))
367
            {
368
              /* OK, this is a bit convoluted.  We can't just make a copy
369
                 of the pointer type and modify its TREE_TYPE, because if
370
                 we change the attributes of the target type the pointer
371
                 type needs to have a different TYPE_MAIN_VARIANT.  So we
372
                 pull out the target type now, frob it as appropriate, and
373
                 rebuild the pointer type later.
374
 
375
                 This would all be simpler if attributes were part of the
376
                 declarator, grumble grumble.  */
377
              fn_ptr_tmp = TREE_TYPE (*anode);
378
              fn_ptr_quals = TYPE_QUALS (*anode);
379
              anode = &fn_ptr_tmp;
380
              flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
381
            }
382
          else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
383
            {
384
              /* Pass on this attribute to be tried again.  */
385
              returned_attrs = tree_cons (name, args, returned_attrs);
386
              continue;
387
            }
388
 
389
          if (TREE_CODE (*anode) != FUNCTION_TYPE
390
              && TREE_CODE (*anode) != METHOD_TYPE)
391
            {
392
              warning (OPT_Wattributes,
393
                       "%qE attribute only applies to function types",
394
                       name);
395
              continue;
396
            }
397
        }
398
 
399
      if (TYPE_P (*anode)
400
          && (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
401
          && TYPE_SIZE (*anode) != NULL_TREE)
402
        {
403
          warning (OPT_Wattributes, "type attributes ignored after type is already defined");
404
          continue;
405
        }
406
 
407
      if (spec->handler != NULL)
408
        returned_attrs = chainon ((*spec->handler) (anode, name, args,
409
                                                    flags, &no_add_attrs),
410
                                  returned_attrs);
411
 
412
      /* Layout the decl in case anything changed.  */
413
      if (spec->type_required && DECL_P (*node)
414
          && (TREE_CODE (*node) == VAR_DECL
415
              || TREE_CODE (*node) == PARM_DECL
416
              || TREE_CODE (*node) == RESULT_DECL))
417
        relayout_decl (*node);
418
 
419
      if (!no_add_attrs)
420
        {
421
          tree old_attrs;
422
          tree a;
423
 
424
          if (DECL_P (*anode))
425
            old_attrs = DECL_ATTRIBUTES (*anode);
426
          else
427
            old_attrs = TYPE_ATTRIBUTES (*anode);
428
 
429
          for (a = lookup_attribute (spec->name, old_attrs);
430
               a != NULL_TREE;
431
               a = lookup_attribute (spec->name, TREE_CHAIN (a)))
432
            {
433
              if (simple_cst_equal (TREE_VALUE (a), args) == 1)
434
                break;
435
            }
436
 
437
          if (a == NULL_TREE)
438
            {
439
              /* This attribute isn't already in the list.  */
440
              if (DECL_P (*anode))
441
                DECL_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
442
              else if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
443
                {
444
                  TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
445
                  /* If this is the main variant, also push the attributes
446
                     out to the other variants.  */
447
                  if (*anode == TYPE_MAIN_VARIANT (*anode))
448
                    {
449
                      tree variant;
450
                      for (variant = *anode; variant;
451
                           variant = TYPE_NEXT_VARIANT (variant))
452
                        {
453
                          if (TYPE_ATTRIBUTES (variant) == old_attrs)
454
                            TYPE_ATTRIBUTES (variant)
455
                              = TYPE_ATTRIBUTES (*anode);
456
                          else if (!lookup_attribute
457
                                   (spec->name, TYPE_ATTRIBUTES (variant)))
458
                            TYPE_ATTRIBUTES (variant) = tree_cons
459
                              (name, args, TYPE_ATTRIBUTES (variant));
460
                        }
461
                    }
462
                }
463
              else
464
                *anode = build_type_attribute_variant (*anode,
465
                                                       tree_cons (name, args,
466
                                                                  old_attrs));
467
            }
468
        }
469
 
470
      if (fn_ptr_tmp)
471
        {
472
          /* Rebuild the function pointer type and put it in the
473
             appropriate place.  */
474
          fn_ptr_tmp = build_pointer_type (fn_ptr_tmp);
475
          if (fn_ptr_quals)
476
            fn_ptr_tmp = build_qualified_type (fn_ptr_tmp, fn_ptr_quals);
477
          if (DECL_P (*node))
478
            TREE_TYPE (*node) = fn_ptr_tmp;
479
          else
480
            {
481
              gcc_assert (TREE_CODE (*node) == POINTER_TYPE);
482
              *node = fn_ptr_tmp;
483
            }
484
        }
485
    }
486
 
487
  return returned_attrs;
488
}
489
 
490
/* Subroutine of set_method_tm_attributes.  Apply TM attribute ATTR
491
   to the method FNDECL.  */
492
 
493
void
494
apply_tm_attr (tree fndecl, tree attr)
495
{
496
  decl_attributes (&TREE_TYPE (fndecl), tree_cons (attr, NULL, NULL), 0);
497
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.