OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / attribs.c
index 31b92ca..dbce181 100644 (file)
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "target.h"
 #include "langhooks.h"
 #include "hashtab.h"
+#include "c-common.h"
 
 static void init_attributes (void);
 
@@ -206,8 +207,9 @@ lookup_attribute_spec (tree name)
   attr.str = IDENTIFIER_POINTER (name);
   attr.length = IDENTIFIER_LENGTH (name);
   extract_attribute_substring (&attr);
-  return htab_find_with_hash (attribute_hash, &attr,
-                             substring_hash (attr.str, attr.length));
+  return (const struct attribute_spec *)
+    htab_find_with_hash (attribute_hash, &attr,
+                        substring_hash (attr.str, attr.length));
 }
 \f
 /* Process the attributes listed in ATTRIBUTES and install them in *NODE,
@@ -225,9 +227,47 @@ decl_attributes (tree *node, tree attributes, int flags)
   tree a;
   tree returned_attrs = NULL_TREE;
 
+  if (TREE_TYPE (*node) == error_mark_node)
+    return NULL_TREE;
+
   if (!attributes_initialized)
     init_attributes ();
 
+  /* If this is a function and the user used #pragma GCC optimize, add the
+     options to the attribute((optimize(...))) list.  */
+  if (TREE_CODE (*node) == FUNCTION_DECL && current_optimize_pragma)
+    {
+      tree cur_attr = lookup_attribute ("optimize", attributes);
+      tree opts = copy_list (current_optimize_pragma);
+
+      if (! cur_attr)
+       attributes
+         = tree_cons (get_identifier ("optimize"), opts, attributes);
+      else
+       TREE_VALUE (cur_attr) = chainon (opts, TREE_VALUE (cur_attr));
+    }
+
+  if (TREE_CODE (*node) == FUNCTION_DECL
+      && optimization_current_node != optimization_default_node
+      && !DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node))
+    DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node) = optimization_current_node;
+
+  /* If this is a function and the user used #pragma GCC target, add the
+     options to the attribute((target(...))) list.  */
+  if (TREE_CODE (*node) == FUNCTION_DECL
+      && current_target_pragma
+      && targetm.target_option.valid_attribute_p (*node, NULL_TREE,
+                                                 current_target_pragma, 0))
+    {
+      tree cur_attr = lookup_attribute ("target", attributes);
+      tree opts = copy_list (current_target_pragma);
+
+      if (! cur_attr)
+       attributes = tree_cons (get_identifier ("target"), opts, attributes);
+      else
+       TREE_VALUE (cur_attr) = chainon (opts, TREE_VALUE (cur_attr));
+    }
+
   targetm.insert_attributes (*node, &attributes);
 
   for (a = attributes; a; a = TREE_CHAIN (a))
@@ -280,7 +320,11 @@ decl_attributes (tree *node, tree attributes, int flags)
       if (spec->type_required && DECL_P (*anode))
        {
          anode = &TREE_TYPE (*anode);
-         flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
+         /* Allow ATTR_FLAG_TYPE_IN_PLACE for the type's naming decl.  */
+         if (!(TREE_CODE (*anode) == TYPE_DECL
+               && *anode == TYPE_NAME (TYPE_MAIN_VARIANT
+                                       (TREE_TYPE (*anode)))))
+           flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
        }
 
       if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE