OSDN Git Service

PR target/39590
[pf3gnuchains/gcc-fork.git] / gcc / tree.c
index 03c54cc..0b02377 100644 (file)
@@ -1,6 +1,6 @@
 /* Language-independent node constructors for parse phase of GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -148,8 +148,7 @@ static GTY(()) int next_type_uid = 1;
 /* Since we cannot rehash a type after it is in the table, we have to
    keep the hash code.  */
 
-struct type_hash GTY(())
-{
+struct GTY(()) type_hash {
   unsigned long hash;
   tree type;
 };
@@ -320,15 +319,6 @@ init_ttree (void)
   tree_contains_struct[TRANSLATION_UNIT_DECL][TS_DECL_MINIMAL] = 1;
   tree_contains_struct[LABEL_DECL][TS_DECL_MINIMAL] = 1;
   tree_contains_struct[FIELD_DECL][TS_DECL_MINIMAL] = 1;
-  tree_contains_struct[NAME_MEMORY_TAG][TS_DECL_MINIMAL] = 1;
-  tree_contains_struct[SYMBOL_MEMORY_TAG][TS_DECL_MINIMAL] = 1;
-  tree_contains_struct[MEMORY_PARTITION_TAG][TS_DECL_MINIMAL] = 1;
-
-  tree_contains_struct[NAME_MEMORY_TAG][TS_MEMORY_TAG] = 1;
-  tree_contains_struct[SYMBOL_MEMORY_TAG][TS_MEMORY_TAG] = 1;
-  tree_contains_struct[MEMORY_PARTITION_TAG][TS_MEMORY_TAG] = 1;
-
-  tree_contains_struct[MEMORY_PARTITION_TAG][TS_MEMORY_PARTITION_TAG] = 1;
 
   tree_contains_struct[VAR_DECL][TS_DECL_WITH_VIS] = 1;
   tree_contains_struct[FUNCTION_DECL][TS_DECL_WITH_VIS] = 1;
@@ -465,11 +455,6 @@ tree_code_size (enum tree_code code)
            return sizeof (struct tree_type_decl);
          case FUNCTION_DECL:
            return sizeof (struct tree_function_decl);
-         case NAME_MEMORY_TAG:
-         case SYMBOL_MEMORY_TAG:
-           return sizeof (struct tree_memory_tag);
-         case MEMORY_PARTITION_TAG:
-           return sizeof (struct tree_memory_partition_tag);
          default:
            return sizeof (struct tree_decl_non_common);
          }
@@ -1802,6 +1787,18 @@ tree_last (tree chain)
   return chain;
 }
 
+/* Return the node in a chain of nodes whose value is x, NULL if not found.  */
+
+tree
+tree_find_value (tree chain, tree x)
+{
+  tree list;
+  for (list = chain; list; list = TREE_CHAIN (list))
+    if (TREE_VALUE (list) == x)
+       return list;
+  return NULL;
+}
+
 /* Reverse the order of elements in the chain T,
    and return the new head of the chain (old last element).  */
 
@@ -2098,8 +2095,7 @@ staticp (tree arg)
     case COMPONENT_REF:
       /* If the thing being referenced is not a field, then it is
         something language specific.  */
-      if (TREE_CODE (TREE_OPERAND (arg, 1)) != FIELD_DECL)
-       return (*lang_hooks.staticp) (arg);
+      gcc_assert (TREE_CODE (TREE_OPERAND (arg, 1)) == FIELD_DECL);
 
       /* If we are referencing a bitfield, we can't evaluate an
         ADDR_EXPR at compile time and so it isn't a constant.  */
@@ -2122,14 +2118,13 @@ staticp (tree arg)
          && TREE_CODE (TREE_OPERAND (arg, 1)) == INTEGER_CST)
        return staticp (TREE_OPERAND (arg, 0));
       else
-       return false;
+       return NULL;
+
+    case COMPOUND_LITERAL_EXPR:
+      return TREE_STATIC (COMPOUND_LITERAL_EXPR_DECL (arg)) ? arg : NULL;
 
     default:
-      if ((unsigned int) TREE_CODE (arg)
-         >= (unsigned int) LAST_AND_UNUSED_TREE_CODE)
-       return lang_hooks.staticp (arg);
-      else
-       return NULL;
+      return NULL;
     }
 }
 
@@ -2399,10 +2394,6 @@ tree_node_structure (const_tree t)
            return TS_TYPE_DECL;
          case FUNCTION_DECL:
            return TS_FUNCTION_DECL;
-         case SYMBOL_MEMORY_TAG:
-         case NAME_MEMORY_TAG:
-         case MEMORY_PARTITION_TAG:
-           return TS_MEMORY_TAG;
          default:
            return TS_DECL_NON_COMMON;
          }
@@ -3423,9 +3414,8 @@ build5_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
 }
 
 tree
-build7_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
-            tree arg2, tree arg3, tree arg4, tree arg5,
-            tree arg6 MEM_STAT_DECL)
+build6_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
+            tree arg2, tree arg3, tree arg4, tree arg5 MEM_STAT_DECL)
 {
   bool constant, read_only, side_effects;
   tree t;
@@ -3443,7 +3433,6 @@ build7_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
   PROCESS_ARG(3);
   PROCESS_ARG(4);
   PROCESS_ARG(5);
-  PROCESS_ARG(6);
 
   TREE_SIDE_EFFECTS (t) = side_effects;
   TREE_THIS_VOLATILE (t) = 0;
@@ -3594,7 +3583,8 @@ set_expr_locus (tree node, source_location *loc)
 
    LOC is the location to use in tree T.  */
 
-void protected_set_expr_location (tree t, location_t loc)
+void
+protected_set_expr_location (tree t, location_t loc)
 {
   if (t && CAN_HAVE_LOCATION_P (t))
     SET_EXPR_LOCATION (t, loc);
@@ -6260,6 +6250,61 @@ build_complex_type (tree component_type)
 
   return build_qualified_type (t, TYPE_QUALS (component_type));
 }
+
+/* If TYPE is a real or complex floating-point type and the target
+   does not directly support arithmetic on TYPE then return the wider
+   type to be used for arithmetic on TYPE.  Otherwise, return
+   NULL_TREE.  */
+
+tree
+excess_precision_type (tree type)
+{
+  if (flag_excess_precision != EXCESS_PRECISION_FAST)
+    {
+      int flt_eval_method = TARGET_FLT_EVAL_METHOD;
+      switch (TREE_CODE (type))
+       {
+       case REAL_TYPE:
+         switch (flt_eval_method)
+           {
+           case 1:
+             if (TYPE_MODE (type) == TYPE_MODE (float_type_node))
+               return double_type_node;
+             break;
+           case 2:
+             if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
+                 || TYPE_MODE (type) == TYPE_MODE (double_type_node))
+               return long_double_type_node;
+             break;
+           default:
+             gcc_unreachable ();
+           }
+         break;
+       case COMPLEX_TYPE:
+         if (TREE_CODE (TREE_TYPE (type)) != REAL_TYPE)
+           return NULL_TREE;
+         switch (flt_eval_method)
+           {
+           case 1:
+             if (TYPE_MODE (TREE_TYPE (type)) == TYPE_MODE (float_type_node))
+               return complex_double_type_node;
+             break;
+           case 2:
+             if (TYPE_MODE (TREE_TYPE (type)) == TYPE_MODE (float_type_node)
+                 || (TYPE_MODE (TREE_TYPE (type))
+                     == TYPE_MODE (double_type_node)))
+               return complex_long_double_type_node;
+             break;
+           default:
+             gcc_unreachable ();
+           }
+         break;
+       default:
+         break;
+       }
+    }
+  return NULL_TREE;
+}
 \f
 /* Return OP, stripped of any conversions to wider types as much as is safe.
    Converting the value back to OP's type makes a value equivalent to OP.
@@ -7805,8 +7850,10 @@ build_common_builtin_nodes (void)
        tmp = tree_cons (NULL_TREE, inner_type, tmp);
        ftype = build_function_type (type, tmp);
 
-        mcode = BUILT_IN_COMPLEX_MUL_MIN + mode - MIN_MODE_COMPLEX_FLOAT;
-        dcode = BUILT_IN_COMPLEX_DIV_MIN + mode - MIN_MODE_COMPLEX_FLOAT;
+        mcode = ((enum built_in_function)
+                (BUILT_IN_COMPLEX_MUL_MIN + mode - MIN_MODE_COMPLEX_FLOAT));
+        dcode = ((enum built_in_function)
+                (BUILT_IN_COMPLEX_DIV_MIN + mode - MIN_MODE_COMPLEX_FLOAT));
 
         for (p = GET_MODE_NAME (mode), q = mode_name_buf; *p; p++, q++)
          *q = TOLOWER (*p);
@@ -7925,6 +7972,19 @@ build_vector_type (tree innertype, int nunits)
   return make_vector_type (innertype, nunits, VOIDmode);
 }
 
+/* Similarly, but takes the inner type and number of units, which must be
+   a power of two.  */
+
+tree
+build_opaque_vector_type (tree innertype, int nunits)
+{
+  tree t;
+  innertype = build_distinct_type_copy (innertype);
+  t = make_vector_type (innertype, nunits, VOIDmode);
+  TYPE_VECTOR_OPAQUE (t) = true;
+  return t;
+}
+
 
 /* Build RESX_EXPR with given REGION_NUMBER.  */
 tree
@@ -9013,26 +9073,6 @@ prototype_p (tree fntype)
   return (t != NULL_TREE);
 }
 
-/* Return the number of arguments that a function has.  */
-
-int
-function_args_count (tree fntype)
-{
-  function_args_iterator args_iter;
-  tree t;
-  int num = 0;
-
-  if (fntype)
-    {
-      FOREACH_FUNCTION_ARGS(fntype, t, args_iter)
-       {
-         num++;
-       }
-    }
-
-  return num;
-}
-
 /* If BLOCK is inlined from an __attribute__((__artificial__))
    routine, return pointer to location from where it has been
    called.  */
@@ -9071,6 +9111,42 @@ block_nonartificial_location (tree block)
   return ret;
 }
 
+
+/* If EXP is inlined from an __attribute__((__artificial__))
+   function, return the location of the original call expression.  */
+
+location_t
+tree_nonartificial_location (tree exp)
+{
+  tree block = TREE_BLOCK (exp);
+
+  while (block
+        && TREE_CODE (block) == BLOCK
+        && BLOCK_ABSTRACT_ORIGIN (block))
+    {
+      tree ao = BLOCK_ABSTRACT_ORIGIN (block);
+
+      do
+       {
+         if (TREE_CODE (ao) == FUNCTION_DECL
+             && DECL_DECLARED_INLINE_P (ao)
+             && lookup_attribute ("artificial", DECL_ATTRIBUTES (ao)))
+           return BLOCK_SOURCE_LOCATION (block);
+         else if (TREE_CODE (ao) == BLOCK
+                  && BLOCK_SUPERCONTEXT (ao) != ao)
+           ao = BLOCK_SUPERCONTEXT (ao);
+         else
+           break;
+       }
+      while (ao);
+
+      block = BLOCK_SUPERCONTEXT (block);
+    }
+
+  return EXPR_LOCATION (exp);
+}
+
+
 /* These are the hash table functions for the hash table of OPTIMIZATION_NODEq
    nodes.  */
 
@@ -9199,4 +9275,49 @@ build_target_option_node (void)
   return t;
 }
 
+/* Determine the "ultimate origin" of a block.  The block may be an inlined
+   instance of an inlined instance of a block which is local to an inline
+   function, so we have to trace all of the way back through the origin chain
+   to find out what sort of node actually served as the original seed for the
+   given block.  */
+
+tree
+block_ultimate_origin (const_tree block)
+{
+  tree immediate_origin = BLOCK_ABSTRACT_ORIGIN (block);
+
+  /* output_inline_function sets BLOCK_ABSTRACT_ORIGIN for all the
+     nodes in the function to point to themselves; ignore that if
+     we're trying to output the abstract instance of this function.  */
+  if (BLOCK_ABSTRACT (block) && immediate_origin == block)
+    return NULL_TREE;
+
+  if (immediate_origin == NULL_TREE)
+    return NULL_TREE;
+  else
+    {
+      tree ret_val;
+      tree lookahead = immediate_origin;
+
+      do
+       {
+         ret_val = lookahead;
+         lookahead = (TREE_CODE (ret_val) == BLOCK
+                      ? BLOCK_ABSTRACT_ORIGIN (ret_val) : NULL);
+       }
+      while (lookahead != NULL && lookahead != ret_val);
+
+      /* The block's abstract origin chain may not be the *ultimate* origin of
+        the block. It could lead to a DECL that has an abstract origin set.
+        If so, we want that DECL's abstract origin (which is what DECL_ORIGIN
+        will give us if it has one).  Note that DECL's abstract origins are
+        supposed to be the most distant ancestor (or so decl_ultimate_origin
+        claims), so we don't need to loop following the DECL origins.  */
+      if (DECL_P (ret_val))
+       return DECL_ORIGIN (ret_val);
+
+      return ret_val;
+    }
+}
+
 #include "gt-tree.h"