OSDN Git Service

* parser.c (cp_parser_init_declarator): Pass LOOKUP_NORMAL
[pf3gnuchains/gcc-fork.git] / gcc / cfgexpand.c
index 771ed47..fef3190 100644 (file)
@@ -344,7 +344,7 @@ aggregate_contains_union_type (tree type)
   if (TREE_CODE (type) != RECORD_TYPE)
     return false;
 
-  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+  for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
     if (TREE_CODE (field) == FIELD_DECL)
       if (aggregate_contains_union_type (TREE_TYPE (field)))
        return true;
@@ -1019,7 +1019,7 @@ expand_used_vars_for_block (tree block, bool toplevel)
   old_sv_num = toplevel ? 0 : stack_vars_num;
 
   /* Expand all variables at this level.  */
-  for (t = BLOCK_VARS (block); t ; t = TREE_CHAIN (t))
+  for (t = BLOCK_VARS (block); t ; t = DECL_CHAIN (t))
     if (TREE_USED (t))
       expand_one_var (t, toplevel, true);
 
@@ -1051,7 +1051,7 @@ clear_tree_used (tree block)
 {
   tree t;
 
-  for (t = BLOCK_VARS (block); t ; t = TREE_CHAIN (t))
+  for (t = BLOCK_VARS (block); t ; t = DECL_CHAIN (t))
     /* if (!TREE_STATIC (t) && !DECL_EXTERNAL (t)) */
       TREE_USED (t) = 0;
 
@@ -1210,7 +1210,7 @@ account_used_vars_for_block (tree block, bool toplevel)
   HOST_WIDE_INT size = 0;
 
   /* Expand all variables at this level.  */
-  for (t = BLOCK_VARS (block); t ; t = TREE_CHAIN (t))
+  for (t = BLOCK_VARS (block); t ; t = DECL_CHAIN (t))
     if (TREE_USED (t))
       size += expand_one_var (t, toplevel, false);
 
@@ -1226,9 +1226,10 @@ static void
 init_vars_expansion (void)
 {
   tree t;
+  unsigned ix;
   /* Set TREE_USED on all variables in the local_decls.  */
-  for (t = cfun->local_decls; t; t = TREE_CHAIN (t))
-    TREE_USED (TREE_VALUE (t)) = 1;
+  FOR_EACH_LOCAL_DECL (cfun, ix, t)
+    TREE_USED (t) = 1;
 
   /* Clear TREE_USED on all variables associated with a block scope.  */
   clear_tree_used (DECL_INITIAL (current_function_decl));
@@ -1251,8 +1252,8 @@ fini_vars_expansion (void)
   stack_vars_alloc = stack_vars_num = 0;
 }
 
-/* Make a fair guess for the size of the stack frame of the current
-   function.  This doesn't have to be exact, the result is only used
+/* Make a fair guess for the size of the stack frame of the decl
+   passed.  This doesn't have to be exact, the result is only used
    in the inline heuristics.  So we don't want to run the full stack
    var packing algorithm (which is quadratic in the number of stack
    vars).  Instead, we calculate the total size of all stack vars.
@@ -1260,18 +1261,20 @@ fini_vars_expansion (void)
    vars doesn't happen very often.  */
 
 HOST_WIDE_INT
-estimated_stack_frame_size (void)
+estimated_stack_frame_size (tree decl)
 {
   HOST_WIDE_INT size = 0;
   size_t i;
-  tree t, outer_block = DECL_INITIAL (current_function_decl);
+  tree var, outer_block = DECL_INITIAL (current_function_decl);
+  unsigned ix;
+  tree old_cur_fun_decl = current_function_decl;
+  current_function_decl = decl;
+  push_cfun (DECL_STRUCT_FUNCTION (decl));
 
   init_vars_expansion ();
 
-  for (t = cfun->local_decls; t; t = TREE_CHAIN (t))
+  FOR_EACH_LOCAL_DECL (cfun, ix, var)
     {
-      tree var = TREE_VALUE (t);
-
       if (TREE_USED (var))
         size += expand_one_var (var, true, false);
       TREE_USED (var) = 1;
@@ -1287,7 +1290,8 @@ estimated_stack_frame_size (void)
       size += account_stack_vars ();
       fini_vars_expansion ();
     }
-
+  pop_cfun ();
+  current_function_decl = old_cur_fun_decl;
   return size;
 }
 
@@ -1296,9 +1300,10 @@ estimated_stack_frame_size (void)
 static void
 expand_used_vars (void)
 {
-  tree t, next, outer_block = DECL_INITIAL (current_function_decl);
-  tree maybe_local_decls = NULL_TREE;
+  tree var, outer_block = DECL_INITIAL (current_function_decl);
+  VEC(tree,heap) *maybe_local_decls = NULL;
   unsigned i;
+  unsigned len;
 
   /* Compute the phase of the stack frame for this function.  */
   {
@@ -1333,15 +1338,12 @@ expand_used_vars (void)
 
   /* At this point all variables on the local_decls with TREE_USED
      set are not associated with any block scope.  Lay them out.  */
-  t = cfun->local_decls;
-  cfun->local_decls = NULL_TREE;
-  for (; t; t = next)
+
+  len = VEC_length (tree, cfun->local_decls);
+  FOR_EACH_LOCAL_DECL (cfun, i, var)
     {
-      tree var = TREE_VALUE (t);
       bool expand_now = false;
 
-      next = TREE_CHAIN (t);
-
       /* Expanded above already.  */
       if (is_gimple_reg (var))
        {
@@ -1377,25 +1379,29 @@ expand_used_vars (void)
          /* Keep artificial non-ignored vars in cfun->local_decls
             chain until instantiate_decls.  */
          if (rtl && (MEM_P (rtl) || GET_CODE (rtl) == CONCAT))
-           {
-             TREE_CHAIN (t) = cfun->local_decls;
-             cfun->local_decls = t;
-             continue;
-           }
+           add_local_decl (cfun, var);
          else if (rtl == NULL_RTX)
-           {
-             /* If rtl isn't set yet, which can happen e.g. with
-                -fstack-protector, retry before returning from this
-                function.  */
-             TREE_CHAIN (t) = maybe_local_decls;
-             maybe_local_decls = t;
-             continue;
-           }
+           /* If rtl isn't set yet, which can happen e.g. with
+              -fstack-protector, retry before returning from this
+              function.  */
+           VEC_safe_push (tree, heap, maybe_local_decls, var);
        }
-
-      ggc_free (t);
     }
 
+  /* We duplicated some of the decls in CFUN->LOCAL_DECLS.
+
+     +-----------------+-----------------+
+     | ...processed... | ...duplicates...|
+     +-----------------+-----------------+
+                       ^
+                      +-- LEN points here.
+
+     We just want the duplicates, as those are the artificial
+     non-ignored vars that we want to keep until instantiate_decls.
+     Move them down and truncate the array.  */
+  if (!VEC_empty (tree, cfun->local_decls))
+    VEC_block_remove (tree, cfun->local_decls, 0, len);
+
   /* At this point, all variables within the block tree with TREE_USED
      set are actually used by the optimized function.  Lay them out.  */
   expand_used_vars_for_block (outer_block, true);
@@ -1452,24 +1458,16 @@ expand_used_vars (void)
   /* If there were any artificial non-ignored vars without rtl
      found earlier, see if deferred stack allocation hasn't assigned
      rtl to them.  */
-  for (t = maybe_local_decls; t; t = next)
+  FOR_EACH_VEC_ELT_REVERSE (tree, maybe_local_decls, i, var)
     {
-      tree var = TREE_VALUE (t);
       rtx rtl = DECL_RTL_IF_SET (var);
 
-      next = TREE_CHAIN (t);
-
       /* Keep artificial non-ignored vars in cfun->local_decls
         chain until instantiate_decls.  */
       if (rtl && (MEM_P (rtl) || GET_CODE (rtl) == CONCAT))
-       {
-         TREE_CHAIN (t) = cfun->local_decls;
-         cfun->local_decls = t;
-         continue;
-       }
-
-      ggc_free (t);
+       add_local_decl (cfun, var);
     }
+  VEC_free (tree, heap, maybe_local_decls);
 
   /* If the target requires that FRAME_OFFSET be aligned, do it.  */
   if (STACK_ALIGNMENT_NEEDED)
@@ -2239,7 +2237,6 @@ expand_debug_expr (tree exp)
   enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
   int unsignedp = TYPE_UNSIGNED (TREE_TYPE (exp));
   addr_space_t as;
-  enum machine_mode address_mode;
 
   switch (TREE_CODE_CLASS (TREE_CODE (exp)))
     {
@@ -2430,7 +2427,9 @@ expand_debug_expr (tree exp)
          op0 = simplify_gen_subreg (mode, op0, inner_mode,
                                     subreg_lowpart_offset (mode,
                                                            inner_mode));
-       else if (unsignedp)
+       else if (TREE_CODE_CLASS (TREE_CODE (exp)) == tcc_unary
+                ? TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0)))
+                : unsignedp)
          op0 = gen_rtx_ZERO_EXTEND (mode, op0);
        else
          op0 = gen_rtx_SIGN_EXTEND (mode, op0);
@@ -2444,28 +2443,15 @@ expand_debug_expr (tree exp)
        return NULL;
       /* Fallthru.  */
     case INDIRECT_REF:
-    case ALIGN_INDIRECT_REF:
     case MISALIGNED_INDIRECT_REF:
       op0 = expand_debug_expr (TREE_OPERAND (exp, 0));
       if (!op0)
        return NULL;
 
       if (POINTER_TYPE_P (TREE_TYPE (exp)))
-       {
-         as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp)));
-         address_mode = targetm.addr_space.address_mode (as);
-       }
+       as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp)));
       else
-       {
-         as = ADDR_SPACE_GENERIC;
-         address_mode = Pmode;
-       }
-
-      if (TREE_CODE (exp) == ALIGN_INDIRECT_REF)
-       {
-         int align = TYPE_ALIGN_UNIT (TREE_TYPE (exp));
-         op0 = gen_rtx_AND (address_mode, op0, GEN_INT (-align));
-       }
+       as = ADDR_SPACE_GENERIC;
 
       op0 = gen_rtx_MEM (mode, op0);