00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "system.h"
00024 #include "coretypes.h"
00025 #include "tm.h"
00026 #include "tree.h"
00027 #include "flags.h"
00028 #include "toplev.h"
00029 #include "output.h"
00030 #include "rtl.h"
00031 #include "ggc.h"
00032 #include "tm_p.h"
00033 #include "cpplib.h"
00034 #include "target.h"
00035 #include "langhooks.h"
00036
00037 static void init_attributes (void);
00038
00039
00040
00041 static const struct attribute_spec *attribute_tables[4];
00042
00043 static bool attributes_initialized = false;
00044
00045
00046 static const struct attribute_spec empty_attribute_table[] =
00047 {
00048 { NULL, 0, 0, false, false, false, NULL }
00049 };
00050
00051
00052
00053
00054 static void
00055 init_attributes (void)
00056 {
00057 size_t i;
00058
00059 attribute_tables[0] = lang_hooks.common_attribute_table;
00060 attribute_tables[1] = lang_hooks.attribute_table;
00061 attribute_tables[2] = lang_hooks.format_attribute_table;
00062 attribute_tables[3] = targetm.attribute_table;
00063
00064
00065 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
00066 if (attribute_tables[i] == NULL)
00067 attribute_tables[i] = empty_attribute_table;
00068
00069 #ifdef ENABLE_CHECKING
00070
00071 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
00072 {
00073 int j;
00074
00075 for (j = 0; attribute_tables[i][j].name != NULL; j++)
00076 {
00077
00078 const char *name = attribute_tables[i][j].name;
00079 int len = strlen (name);
00080
00081 gcc_assert (!(name[0] == '_' && name[1] == '_'
00082 && name[len - 1] == '_' && name[len - 2] == '_'));
00083
00084
00085 gcc_assert (attribute_tables[i][j].min_length >= 0);
00086
00087 gcc_assert (attribute_tables[i][j].max_length == -1
00088 || (attribute_tables[i][j].max_length
00089 >= attribute_tables[i][j].min_length));
00090
00091
00092 gcc_assert (!attribute_tables[i][j].decl_required
00093 || !attribute_tables[i][j].type_required);
00094
00095
00096
00097 gcc_assert (!attribute_tables[i][j].function_type_required
00098 || attribute_tables[i][j].type_required);
00099 }
00100 }
00101
00102
00103 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
00104 {
00105 int j, k;
00106 for (j = 0; attribute_tables[i][j].name != NULL; j++)
00107 for (k = j + 1; attribute_tables[i][k].name != NULL; k++)
00108 gcc_assert (strcmp (attribute_tables[i][j].name,
00109 attribute_tables[i][k].name));
00110 }
00111
00112 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
00113 {
00114 size_t j, k, l;
00115
00116 for (j = i + 1; j < ARRAY_SIZE (attribute_tables); j++)
00117 for (k = 0; attribute_tables[i][k].name != NULL; k++)
00118 for (l = 0; attribute_tables[j][l].name != NULL; l++)
00119 gcc_assert (strcmp (attribute_tables[i][k].name,
00120 attribute_tables[j][l].name));
00121 }
00122 #endif
00123
00124 attributes_initialized = true;
00125 }
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 tree
00137 decl_attributes (tree *node, tree attributes, int flags)
00138 {
00139 tree a;
00140 tree returned_attrs = NULL_TREE;
00141
00142 if (!attributes_initialized)
00143 init_attributes ();
00144
00145 targetm.insert_attributes (*node, &attributes);
00146
00147 for (a = attributes; a; a = TREE_CHAIN (a))
00148 {
00149 tree name = TREE_PURPOSE (a);
00150 tree args = TREE_VALUE (a);
00151 tree *anode = node;
00152 const struct attribute_spec *spec = NULL;
00153 bool no_add_attrs = 0;
00154 tree fn_ptr_tmp = NULL_TREE;
00155 size_t i;
00156
00157 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
00158 {
00159 int j;
00160
00161 for (j = 0; attribute_tables[i][j].name != NULL; j++)
00162 {
00163 if (is_attribute_p (attribute_tables[i][j].name, name))
00164 {
00165 spec = &attribute_tables[i][j];
00166 break;
00167 }
00168 }
00169 if (spec != NULL)
00170 break;
00171 }
00172
00173 if (spec == NULL)
00174 {
00175 warning (OPT_Wattributes, "%qs attribute directive ignored",
00176 IDENTIFIER_POINTER (name));
00177 continue;
00178 }
00179 else if (list_length (args) < spec->min_length
00180 || (spec->max_length >= 0
00181 && list_length (args) > spec->max_length))
00182 {
00183 error ("wrong number of arguments specified for %qs attribute",
00184 IDENTIFIER_POINTER (name));
00185 continue;
00186 }
00187
00188 if (spec->decl_required && !DECL_P (*anode))
00189 {
00190 if (flags & ((int) ATTR_FLAG_DECL_NEXT
00191 | (int) ATTR_FLAG_FUNCTION_NEXT
00192 | (int) ATTR_FLAG_ARRAY_NEXT))
00193 {
00194
00195 returned_attrs = tree_cons (name, args, returned_attrs);
00196 continue;
00197 }
00198 else
00199 {
00200 warning (OPT_Wattributes, "%qs attribute does not apply to types",
00201 IDENTIFIER_POINTER (name));
00202 continue;
00203 }
00204 }
00205
00206
00207
00208
00209
00210 if (spec->type_required && DECL_P (*anode))
00211 {
00212 anode = &TREE_TYPE (*anode);
00213 flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
00214 }
00215
00216 if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE
00217 && TREE_CODE (*anode) != METHOD_TYPE)
00218 {
00219 if (TREE_CODE (*anode) == POINTER_TYPE
00220 && (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE
00221 || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE))
00222 {
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 fn_ptr_tmp = TREE_TYPE (*anode);
00233 anode = &fn_ptr_tmp;
00234 flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
00235 }
00236 else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
00237 {
00238
00239 returned_attrs = tree_cons (name, args, returned_attrs);
00240 continue;
00241 }
00242
00243 if (TREE_CODE (*anode) != FUNCTION_TYPE
00244 && TREE_CODE (*anode) != METHOD_TYPE)
00245 {
00246 warning (OPT_Wattributes,
00247 "%qs attribute only applies to function types",
00248 IDENTIFIER_POINTER (name));
00249 continue;
00250 }
00251 }
00252
00253 if (TYPE_P (*anode)
00254 && (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
00255 && TYPE_SIZE (*anode) != NULL_TREE)
00256 {
00257 warning (OPT_Wattributes, "type attributes ignored after type is already defined");
00258 continue;
00259 }
00260
00261 if (spec->handler != NULL)
00262 returned_attrs = chainon ((*spec->handler) (anode, name, args,
00263 flags, &no_add_attrs),
00264 returned_attrs);
00265
00266
00267 if (spec->type_required && DECL_P (*node)
00268 && (TREE_CODE (*node) == VAR_DECL
00269 || TREE_CODE (*node) == PARM_DECL
00270 || TREE_CODE (*node) == RESULT_DECL))
00271 relayout_decl (*node);
00272
00273 if (!no_add_attrs)
00274 {
00275 tree old_attrs;
00276 tree a;
00277
00278 if (DECL_P (*anode))
00279 old_attrs = DECL_ATTRIBUTES (*anode);
00280 else
00281 old_attrs = TYPE_ATTRIBUTES (*anode);
00282
00283 for (a = lookup_attribute (spec->name, old_attrs);
00284 a != NULL_TREE;
00285 a = lookup_attribute (spec->name, TREE_CHAIN (a)))
00286 {
00287 if (simple_cst_equal (TREE_VALUE (a), args) == 1)
00288 break;
00289 }
00290
00291 if (a == NULL_TREE)
00292 {
00293
00294 if (DECL_P (*anode))
00295 DECL_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
00296 else if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
00297 {
00298 TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
00299
00300
00301 if (*anode == TYPE_MAIN_VARIANT (*anode))
00302 {
00303 tree variant;
00304 for (variant = *anode; variant;
00305 variant = TYPE_NEXT_VARIANT (variant))
00306 {
00307 if (TYPE_ATTRIBUTES (variant) == old_attrs)
00308 TYPE_ATTRIBUTES (variant)
00309 = TYPE_ATTRIBUTES (*anode);
00310 else if (!lookup_attribute
00311 (spec->name, TYPE_ATTRIBUTES (variant)))
00312 TYPE_ATTRIBUTES (variant) = tree_cons
00313 (name, args, TYPE_ATTRIBUTES (variant));
00314 }
00315 }
00316 }
00317 else
00318 *anode = build_type_attribute_variant (*anode,
00319 tree_cons (name, args,
00320 old_attrs));
00321 }
00322 }
00323
00324 if (fn_ptr_tmp)
00325 {
00326
00327
00328 fn_ptr_tmp = build_pointer_type (fn_ptr_tmp);
00329 if (DECL_P (*node))
00330 TREE_TYPE (*node) = fn_ptr_tmp;
00331 else
00332 {
00333 gcc_assert (TREE_CODE (*node) == POINTER_TYPE);
00334 *node = fn_ptr_tmp;
00335 }
00336 }
00337 }
00338
00339 return returned_attrs;
00340 }