00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "config.h"
00027 #include "system.h"
00028 #ifdef SGI_MONGOOSE
00029
00030 #include "rtl.h"
00031 #endif
00032 #include "tree.h"
00033 #include "flags.h"
00034 #include "toplev.h"
00035 #include "output.h"
00036 #ifndef SGI_MONGOOSE
00037 #include "rtl.h"
00038 #endif
00039 #include "ggc.h"
00040 #include "expr.h"
00041 #include "tm_p.h"
00042 #include "cpplib.h"
00043 #include "target.h"
00044 #include "langhooks.h"
00045
00046 static void init_attributes PARAMS ((void));
00047
00048
00049
00050 static const struct attribute_spec *attribute_tables[4];
00051
00052 static bool attributes_initialized = false;
00053
00054
00055 static const struct attribute_spec empty_attribute_table[] =
00056 {
00057 { NULL, 0, 0, false, false, false, NULL }
00058 };
00059
00060
00061
00062
00063 static void
00064 init_attributes ()
00065 {
00066 size_t i;
00067
00068 attribute_tables[0] = lang_hooks.common_attribute_table;
00069 attribute_tables[1] = lang_hooks.attribute_table;
00070 attribute_tables[2] = lang_hooks.format_attribute_table;
00071 attribute_tables[3] = targetm.attribute_table;
00072
00073
00074 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
00075 if (attribute_tables[i] == NULL)
00076 attribute_tables[i] = empty_attribute_table;
00077
00078 #ifdef ENABLE_CHECKING
00079
00080 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
00081 {
00082 int j;
00083
00084 for (j = 0; attribute_tables[i][j].name != NULL; j++)
00085 {
00086
00087 const char *name = attribute_tables[i][j].name;
00088 int len = strlen (name);
00089 if (name[0] == '_' && name[1] == '_'
00090 && name[len - 1] == '_' && name[len - 2] == '_')
00091 abort ();
00092
00093 if (attribute_tables[i][j].min_length < 0)
00094 abort ();
00095 if (attribute_tables[i][j].max_length != -1
00096 && (attribute_tables[i][j].max_length
00097 < attribute_tables[i][j].min_length))
00098 abort ();
00099
00100 if (attribute_tables[i][j].decl_required
00101 && attribute_tables[i][j].type_required)
00102 abort ();
00103
00104
00105 if (attribute_tables[i][j].function_type_required
00106 && !attribute_tables[i][j].type_required)
00107 abort ();
00108 }
00109 }
00110
00111
00112 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
00113 {
00114 int j, k;
00115 for (j = 0; attribute_tables[i][j].name != NULL; j++)
00116 for (k = j + 1; attribute_tables[i][k].name != NULL; k++)
00117 if (!strcmp (attribute_tables[i][j].name,
00118 attribute_tables[i][k].name))
00119 abort ();
00120 }
00121
00122 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
00123 {
00124 size_t j, k, l;
00125
00126 for (j = i + 1; j < ARRAY_SIZE (attribute_tables); j++)
00127 for (k = 0; attribute_tables[i][k].name != NULL; k++)
00128 for (l = 0; attribute_tables[j][l].name != NULL; l++)
00129 if (!strcmp (attribute_tables[i][k].name,
00130 attribute_tables[j][l].name))
00131 abort ();
00132 }
00133 #endif
00134
00135 attributes_initialized = true;
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 tree
00152 decl_attributes (node, attributes, flags)
00153 tree *node, attributes;
00154 int flags;
00155 {
00156 tree a;
00157 tree returned_attrs = NULL_TREE;
00158
00159 if (!attributes_initialized)
00160 init_attributes ();
00161
00162 (*targetm.insert_attributes) (*node, &attributes);
00163
00164 if (DECL_P (*node) && TREE_CODE (*node) == FUNCTION_DECL
00165 && !(flags & (int) ATTR_FLAG_BUILT_IN))
00166 (*lang_hooks.insert_default_attributes) (*node);
00167
00168 for (a = attributes; a; a = TREE_CHAIN (a))
00169 {
00170 tree name = TREE_PURPOSE (a);
00171 tree args = TREE_VALUE (a);
00172 tree *anode = node;
00173 const struct attribute_spec *spec = NULL;
00174 bool no_add_attrs = 0;
00175 size_t i;
00176
00177 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
00178 {
00179 int j;
00180
00181 for (j = 0; attribute_tables[i][j].name != NULL; j++)
00182 {
00183 if (is_attribute_p (attribute_tables[i][j].name, name))
00184 {
00185 spec = &attribute_tables[i][j];
00186 break;
00187 }
00188 }
00189 if (spec != NULL)
00190 break;
00191 }
00192
00193 if (spec == NULL)
00194 {
00195 warning ("`%s' attribute directive ignored",
00196 IDENTIFIER_POINTER (name));
00197 continue;
00198 }
00199 else if (list_length (args) < spec->min_length
00200 || (spec->max_length >= 0
00201 && list_length (args) > spec->max_length))
00202 {
00203 error ("wrong number of arguments specified for `%s' attribute",
00204 IDENTIFIER_POINTER (name));
00205 continue;
00206 }
00207
00208 if (spec->decl_required && !DECL_P (*anode))
00209 {
00210 if (flags & ((int) ATTR_FLAG_DECL_NEXT
00211 | (int) ATTR_FLAG_FUNCTION_NEXT
00212 | (int) ATTR_FLAG_ARRAY_NEXT))
00213 {
00214
00215 returned_attrs = tree_cons (name, args, returned_attrs);
00216 continue;
00217 }
00218 else
00219 {
00220 warning ("`%s' attribute does not apply to types",
00221 IDENTIFIER_POINTER (name));
00222 continue;
00223 }
00224 }
00225
00226
00227
00228
00229
00230 if (spec->type_required && DECL_P (*anode))
00231 {
00232 anode = &TREE_TYPE (*anode);
00233 flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
00234 }
00235
00236 if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE
00237 && TREE_CODE (*anode) != METHOD_TYPE)
00238 {
00239 if (TREE_CODE (*anode) == POINTER_TYPE
00240 && (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE
00241 || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE))
00242 {
00243 if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
00244 *anode = build_type_copy (*anode);
00245 anode = &TREE_TYPE (*anode);
00246 }
00247 else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
00248 {
00249
00250 returned_attrs = tree_cons (name, args, returned_attrs);
00251 continue;
00252 }
00253
00254 if (TREE_CODE (*anode) != FUNCTION_TYPE
00255 && TREE_CODE (*anode) != METHOD_TYPE)
00256 {
00257 warning ("`%s' attribute only applies to function types",
00258 IDENTIFIER_POINTER (name));
00259 continue;
00260 }
00261 }
00262
00263 if (spec->handler != NULL)
00264 returned_attrs = chainon ((*spec->handler) (anode, name, args,
00265 flags, &no_add_attrs),
00266 returned_attrs);
00267
00268
00269 if (spec->type_required && DECL_P (*node)
00270 && (TREE_CODE (*node) == VAR_DECL
00271 || TREE_CODE (*node) == PARM_DECL
00272 || TREE_CODE (*node) == RESULT_DECL))
00273 {
00274
00275 DECL_MODE (*node) = VOIDmode;
00276 DECL_SIZE (*node) = 0;
00277
00278 layout_decl (*node, 0);
00279 }
00280
00281 if (!no_add_attrs)
00282 {
00283 tree old_attrs;
00284 tree a;
00285
00286 if (DECL_P (*anode))
00287 old_attrs = DECL_ATTRIBUTES (*anode);
00288 else
00289 old_attrs = TYPE_ATTRIBUTES (*anode);
00290
00291 for (a = lookup_attribute (spec->name, old_attrs);
00292 a != NULL_TREE;
00293 a = lookup_attribute (spec->name, TREE_CHAIN (a)))
00294 {
00295 if (simple_cst_equal (TREE_VALUE (a), args) == 1)
00296 break;
00297 }
00298
00299 if (a == NULL_TREE)
00300 {
00301
00302 if (DECL_P (*anode))
00303 DECL_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
00304 else if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
00305 TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
00306 else
00307 *anode = build_type_attribute_variant (*anode,
00308 tree_cons (name, args,
00309 old_attrs));
00310 }
00311 }
00312 }
00313
00314 return returned_attrs;
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 void
00328 split_specs_attrs (specs_attrs, declspecs, prefix_attributes)
00329 tree specs_attrs;
00330 tree *declspecs, *prefix_attributes;
00331 {
00332 tree t, s, a, next, specs, attrs;
00333
00334
00335 if (specs_attrs != NULL_TREE
00336 && TREE_CODE (specs_attrs) == INTEGER_CST)
00337 {
00338 *declspecs = NULL_TREE;
00339 *prefix_attributes = NULL_TREE;
00340 return;
00341 }
00342
00343
00344 if (specs_attrs != NULL_TREE
00345 && TREE_CODE (specs_attrs) != TREE_LIST)
00346 {
00347 *declspecs = specs_attrs;
00348 *prefix_attributes = NULL_TREE;
00349 return;
00350 }
00351
00352
00353
00354 specs = s = NULL_TREE;
00355 attrs = a = NULL_TREE;
00356 for (t = specs_attrs; t; t = next)
00357 {
00358 next = TREE_CHAIN (t);
00359
00360 if (TREE_VALUE (t) != NULL_TREE)
00361 {
00362 if (specs == NULL_TREE)
00363 specs = s = t;
00364 else
00365 {
00366 TREE_CHAIN (s) = t;
00367 s = t;
00368 }
00369 }
00370
00371
00372 else if (TREE_PURPOSE (t) != NULL_TREE)
00373 {
00374 if (attrs == NULL_TREE)
00375 attrs = a = TREE_PURPOSE (t);
00376 else
00377 {
00378 TREE_CHAIN (a) = TREE_PURPOSE (t);
00379 a = TREE_PURPOSE (t);
00380 }
00381
00382 while (TREE_CHAIN (a) != NULL_TREE)
00383 a = TREE_CHAIN (a);
00384 }
00385 }
00386
00387
00388 if (s != NULL_TREE)
00389 TREE_CHAIN (s) = NULL_TREE;
00390 if (a != NULL_TREE)
00391 TREE_CHAIN (a) = NULL_TREE;
00392
00393
00394 *declspecs = specs;
00395 *prefix_attributes = attrs;
00396 }
00397
00398
00399
00400
00401
00402
00403
00404 tree
00405 strip_attrs (specs_attrs)
00406 tree specs_attrs;
00407 {
00408 tree specs, attrs;
00409
00410 split_specs_attrs (specs_attrs, &specs, &attrs);
00411
00412 while (attrs)
00413 {
00414 warning ("`%s' attribute ignored",
00415 IDENTIFIER_POINTER (TREE_PURPOSE (attrs)));
00416 attrs = TREE_CHAIN (attrs);
00417 }
00418
00419 return specs;
00420 }
00421