Makefile.in (parse.o, decl.o): Also depend on $(srcdir)/../except.h $(srcdir)/.....
[gcc.git] / gcc / cp / expr.c
index 7411a4eaa0d110e6282c02a311301e56e0167d15..a14695ddd51ff03fbc4c2e829d88f9b526fbc967 100644 (file)
@@ -21,18 +21,21 @@ Boston, MA 02111-1307, USA.  */
 
 
 #include "config.h"
+#include <stdio.h>
 #include "rtl.h"
 #include "tree.h"
 #include "flags.h"
 #include "expr.h"
 #include "cp-tree.h"
 
-#undef NULL
-#define NULL 0
+static tree extract_aggr_init PROTO((tree, tree));
+static tree extract_scalar_init PROTO((tree, tree));
+static rtx cplus_expand_expr PROTO((tree, rtx, enum machine_mode,
+                                   enum expand_modifier));
 
 /* Hook used by expand_expr to expand language-specific tree codes.  */
 
-rtx
+static rtx
 cplus_expand_expr (exp, target, tmode, modifier)
      tree exp;
      rtx target;
@@ -42,11 +45,10 @@ cplus_expand_expr (exp, target, tmode, modifier)
   tree type = TREE_TYPE (exp);
   register enum machine_mode mode = TYPE_MODE (type);
   register enum tree_code code = TREE_CODE (exp);
-  rtx original_target = target;
   int ignore = target == const0_rtx;
 
   if (ignore)
-    target = 0, original_target = 0;
+    target = 0;
 
   /* No sense saving up arithmetic to be done
      if it's all in the wrong mode to form part of an address.
@@ -137,6 +139,18 @@ cplus_expand_expr (exp, target, tmode, modifier)
               result.  The assumptions are true only if the address was
               valid to begin with.  */
            call_target = validize_mem (call_target);
+
+           /* If this is a reference to a symbol, expand_inline_function
+              will do this transformation and return a different target
+              than the one we gave it, though functionally equivalent.  Do
+              the transformation here to avoid confusion.  */
+           if (! cse_not_expected && GET_CODE (call_target) == MEM
+               && GET_CODE (XEXP (call_target, 0)) == SYMBOL_REF)
+             {
+               call_target = gen_rtx
+                 (MEM, mode, memory_address (mode, XEXP (call_target, 0)));
+               MEM_IN_STRUCT_P (call_target) = 1;
+             }
          }
 
        call_exp = build (CALL_EXPR, type, func, args, NULL_TREE);
@@ -165,7 +179,7 @@ cplus_expand_expr (exp, target, tmode, modifier)
 
                    init = maybe_build_cleanup (convert_from_reference (init));
                    if (init != NULL_TREE)
-                     expand_expr (init, 0, 0, 0);
+                     expand_expr (init, const0_rtx, VOIDmode, 0);
                  }
                call_target = return_target = DECL_RTL (slot);
              }
@@ -226,14 +240,6 @@ cplus_expand_expr (exp, target, tmode, modifier)
       expand_throw (TREE_OPERAND (exp, 0));
       return NULL;
 
-    case UNSAVE_EXPR:
-      {
-       rtx temp;
-       temp = expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier);
-       TREE_OPERAND (exp, 0) = unsave_expr_now (TREE_OPERAND (exp, 0));
-       return temp;
-      }
-
     case VEC_INIT_EXPR:
       return expand_expr
        (expand_vec_init
@@ -328,8 +334,8 @@ extract_scalar_init (decl, init)
 
       to = XEXP (r, 0);
 
-      if (! (to == value ||
-            (GET_CODE (to) == SUBREG && XEXP (to, 0) == value)))
+      if (! (to == value
+            || (GET_CODE (to) == SUBREG && XEXP (to, 0) == value)))
        return 0;
 
       r = XEXP (r, 1);
@@ -374,13 +380,14 @@ do_case (start, end)
 {
   tree value1 = NULL_TREE, value2 = NULL_TREE, label;
 
-  if (start && POINTER_TYPE_P (TREE_TYPE (start)))
+  if (start != NULL_TREE && TREE_TYPE (start) != NULL_TREE 
+      && POINTER_TYPE_P (TREE_TYPE (start)))
     error ("pointers are not permitted as case values");
 
   if (end && pedantic)
     pedwarn ("ANSI C++ forbids range expressions in switch statement");
 
-  if (current_template_parms)
+  if (processing_template_decl)
     {
       add_tree (build_min_nt (CASE_LABEL, start, end));
       return;
@@ -443,6 +450,8 @@ do_case (start, end)
        {
          if (end)
            error ("case label within scope of cleanup or variable array");
+         else if (! start)
+           error ("`default' label within scope of cleanup or variable array");
          else
            cp_error ("case label `%E' within scope of cleanup or variable array", start);
        }