OSDN Git Service

PR c++/13693
[pf3gnuchains/gcc-fork.git] / gcc / cp / tree.c
index 64aa2db..7d98128 100644 (file)
@@ -41,7 +41,7 @@ static tree build_cplus_array_type_1 (tree, tree);
 static int list_hash_eq (const void *, const void *);
 static hashval_t list_hash_pieces (tree, tree, tree);
 static hashval_t list_hash (const void *);
-static cp_lvalue_kind lvalue_p_1 (tree, int, int);
+static cp_lvalue_kind lvalue_p_1 (tree, int);
 static tree no_linkage_helper (tree *, int *, void *);
 static tree mark_local_for_remap_r (tree *, int *, void *);
 static tree cp_unsave_r (tree *, int *, void *);
@@ -49,6 +49,7 @@ static tree build_target_expr (tree, tree);
 static tree count_trees_r (tree *, int *, void *);
 static tree verify_stmt_tree_r (tree *, int *, void *);
 static tree find_tree_r (tree *, int *, void *);
+static tree build_local_temp (tree);
 
 static tree handle_java_interface_attribute (tree *, tree, tree, int, bool *);
 static tree handle_com_interface_attribute (tree *, tree, tree, int, bool *);
@@ -60,8 +61,7 @@ static tree handle_init_priority_attribute (tree *, tree, tree, int, bool *);
 
 static cp_lvalue_kind
 lvalue_p_1 (tree ref, 
-            int treat_class_rvalues_as_lvalues, 
-            int allow_cast_as_lvalue)
+            int treat_class_rvalues_as_lvalues)
 {
   cp_lvalue_kind op1_lvalue_kind = clk_none;
   cp_lvalue_kind op2_lvalue_kind = clk_none;
@@ -85,33 +85,27 @@ lvalue_p_1 (tree ref,
     case REALPART_EXPR:
     case IMAGPART_EXPR:
       return lvalue_p_1 (TREE_OPERAND (ref, 0),
-                        treat_class_rvalues_as_lvalues,
-                        allow_cast_as_lvalue);
-
-    case NOP_EXPR:
-      if (allow_cast_as_lvalue)
-       return lvalue_p_1 (TREE_OPERAND (ref, 0),
-                          treat_class_rvalues_as_lvalues,
-                          allow_cast_as_lvalue);
-      else
-       return clk_none;
+                        treat_class_rvalues_as_lvalues);
 
     case COMPONENT_REF:
       op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0),
-                                   treat_class_rvalues_as_lvalues,
-                                   allow_cast_as_lvalue);
-      if (op1_lvalue_kind 
-         /* The "field" can be a FUNCTION_DECL or an OVERLOAD in some
-            situations.  */
-         && TREE_CODE (TREE_OPERAND (ref, 1)) == FIELD_DECL
-         && DECL_C_BIT_FIELD (TREE_OPERAND (ref, 1)))
+                                   treat_class_rvalues_as_lvalues);
+      if (!op1_lvalue_kind 
+         /* The "field" can be a FUNCTION_DECL or an OVERLOAD in some  
+            situations.  */
+         || TREE_CODE (TREE_OPERAND (ref, 1)) != FIELD_DECL)
+       ;
+      else if (DECL_C_BIT_FIELD (TREE_OPERAND (ref, 1)))
        {
          /* Clear the ordinary bit.  If this object was a class
             rvalue we want to preserve that information.  */
          op1_lvalue_kind &= ~clk_ordinary;
-         /* The lvalue is for a btifield.  */
+         /* The lvalue is for a bitfield.  */
          op1_lvalue_kind |= clk_bitfield;
        }
+      else if (DECL_PACKED (TREE_OPERAND (ref, 1)))
+       op1_lvalue_kind |= clk_packed;
+      
       return op1_lvalue_kind;
 
     case STRING_CST:
@@ -133,27 +127,19 @@ lvalue_p_1 (tree ref,
       /* A currently unresolved scope ref.  */
     case SCOPE_REF:
       abort ();
-    case OFFSET_REF:
-      if (TREE_CODE (TREE_OPERAND (ref, 1)) == FUNCTION_DECL)
-       return clk_ordinary;
-      /* Fall through.  */
     case MAX_EXPR:
     case MIN_EXPR:
       op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0),
-                                   treat_class_rvalues_as_lvalues,
-                                   allow_cast_as_lvalue);
+                                   treat_class_rvalues_as_lvalues);
       op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1),
-                                   treat_class_rvalues_as_lvalues,
-                                   allow_cast_as_lvalue);
+                                   treat_class_rvalues_as_lvalues);
       break;
 
     case COND_EXPR:
       op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1),
-                                   treat_class_rvalues_as_lvalues,
-                                   allow_cast_as_lvalue);
+                                   treat_class_rvalues_as_lvalues);
       op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 2),
-                                   treat_class_rvalues_as_lvalues,
-                                   allow_cast_as_lvalue);
+                                   treat_class_rvalues_as_lvalues);
       break;
 
     case MODIFY_EXPR:
@@ -161,8 +147,7 @@ lvalue_p_1 (tree ref,
 
     case COMPOUND_EXPR:
       return lvalue_p_1 (TREE_OPERAND (ref, 1),
-                        treat_class_rvalues_as_lvalues,
-                        allow_cast_as_lvalue);
+                        treat_class_rvalues_as_lvalues);
 
     case TARGET_EXPR:
       return treat_class_rvalues_as_lvalues ? clk_class : clk_none;
@@ -178,6 +163,14 @@ lvalue_p_1 (tree ref,
       return (DECL_NONSTATIC_MEMBER_FUNCTION_P (ref) 
              ? clk_none : clk_ordinary);
 
+    case NON_DEPENDENT_EXPR:
+      /* We must consider NON_DEPENDENT_EXPRs to be lvalues so that
+        things like "&E" where "E" is an expression with a
+        non-dependent type work. It is safe to be lenient because an
+        error will be issued when the template is instantiated if "E"
+        is not an lvalue.  */
+      return clk_ordinary;
+
     default:
       break;
     }
@@ -197,27 +190,15 @@ lvalue_p_1 (tree ref,
   return op1_lvalue_kind;
 }
 
-/* If REF is an lvalue, returns the kind of lvalue that REF is.
-   Otherwise, returns clk_none.  Lvalues can be assigned, unless they
-   have TREE_READONLY, or unless they are FUNCTION_DECLs.  Lvalues can
-   have their address taken, unless they have DECL_REGISTER.  */
-
-cp_lvalue_kind
-real_lvalue_p (tree ref)
-{
-  return lvalue_p_1 (ref, /*treat_class_rvalues_as_lvalues=*/ 0, /*cast*/ 1);
-}
-
 /* Returns the kind of lvalue that REF is, in the sense of
    [basic.lval].  This function should really be named lvalue_p; it
    computes the C++ definition of lvalue.  */
 
 cp_lvalue_kind
-real_non_cast_lvalue_p (tree ref)
+real_lvalue_p (tree ref)
 {
   return lvalue_p_1 (ref, 
-                    /*treat_class_rvalues_as_lvalues=*/0, 
-                    /*allow_cast_as_lvalue=*/0);
+                    /*treat_class_rvalues_as_lvalues=*/0);
 }
 
 /* This differs from real_lvalue_p in that class rvalues are
@@ -227,14 +208,7 @@ int
 lvalue_p (tree ref)
 {
   return 
-    (lvalue_p_1 (ref, /*class rvalue ok*/ 1, /*cast*/ 1) != clk_none);
-}
-
-int
-non_cast_lvalue_p (tree ref)
-{
-  return 
-    (lvalue_p_1 (ref, /*class rvalue ok*/ 1, /*cast*/ 0) != clk_none);
+    (lvalue_p_1 (ref, /*class rvalue ok*/ 1) != clk_none);
 }
 
 /* Return nonzero if REF is an lvalue valid for this language;
@@ -243,21 +217,12 @@ non_cast_lvalue_p (tree ref)
 int
 lvalue_or_else (tree ref, const char* string)
 {
-  int ret = lvalue_p_1 (ref, /* class rvalue ok */ 1, /* cast ok */ 1);
-  int win = (ret != clk_none);
-  if (! win)
-    error ("non-lvalue in %s", string);
-  return win;
-}
-
-int
-non_cast_lvalue_or_else (tree ref, const char* string)
-{
-  int ret = lvalue_p_1 (ref, /* class rvalue ok */ 1, /* cast ok */ 0);
-  int win = (ret != clk_none);
-  if (! win)
-    error ("non-lvalue in %s", string);
-  return win;
+  if (!lvalue_p (ref))
+    {
+      error ("non-lvalue in %s", string);
+      return 0;
+    }
+  return 1;
 }
 
 /* Build a TARGET_EXPR, initializing the DECL with the VALUE.  */
@@ -278,6 +243,19 @@ build_target_expr (tree decl, tree value)
   return t;
 }
 
+/* Return an undeclared local temporary of type TYPE for use in building a
+   TARGET_EXPR.  */
+
+static tree
+build_local_temp (tree type)
+{
+  tree slot = build_decl (VAR_DECL, NULL_TREE, type);
+  DECL_ARTIFICIAL (slot) = 1;
+  DECL_CONTEXT (slot) = current_function_decl;
+  layout_decl (slot, 0);
+  return slot;
+}
+
 /* INIT is a CALL_EXPR which needs info about its target.
    TYPE is the type that this initialization should appear to have.
 
@@ -305,10 +283,7 @@ build_cplus_new (tree type, tree init)
             && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
             && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0)));
 
-  slot = build (VAR_DECL, type);
-  DECL_ARTIFICIAL (slot) = 1;
-  DECL_CONTEXT (slot) = current_function_decl;
-  layout_decl (slot, 0);
+  slot = build_local_temp (type);
 
   /* We split the CALL_EXPR into its function and its arguments here.
      Then, in expand_expr, we put them back together.  The reason for
@@ -342,146 +317,50 @@ tree
 build_target_expr_with_type (tree init, tree type)
 {
   tree slot;
-  tree rval;
+
+  my_friendly_assert (!VOID_TYPE_P (type), 20040130);
 
   if (TREE_CODE (init) == TARGET_EXPR)
     return init;
+  else if (CLASS_TYPE_P (type) && !TYPE_HAS_TRIVIAL_INIT_REF (type)
+          && TREE_CODE (init) != COND_EXPR
+          && TREE_CODE (init) != CONSTRUCTOR
+          && TREE_CODE (init) != VA_ARG_EXPR)
+    /* We need to build up a copy constructor call.  COND_EXPR is a special
+       case because we already have copies on the arms and we don't want
+       another one here.  A CONSTRUCTOR is aggregate initialization, which
+       is handled separately.  A VA_ARG_EXPR is magic creation of an
+       aggregate; there's no additional work to be done.  */
+    return force_rvalue (init);
 
-  slot = build (VAR_DECL, type);
-  DECL_ARTIFICIAL (slot) = 1;
-  DECL_CONTEXT (slot) = current_function_decl;
-  layout_decl (slot, 0);
-  rval = build_target_expr (slot, init);
-
-  return rval;
-}
-
-/* Like build_target_expr_with_type, but use the type of INIT.  */
-
-tree
-get_target_expr (tree init)
-{
-  return build_target_expr_with_type (init, TREE_TYPE (init));
+  slot = build_local_temp (type);
+  return build_target_expr (slot, init);
 }
 
-/* Recursively perform a preorder search EXP for CALL_EXPRs, making
-   copies where they are found.  Returns a deep copy all nodes transitively
-   containing CALL_EXPRs.  */
+/* Like the above function, but without the checking.  This function should
+   only be used by code which is deliberately trying to subvert the type
+   system, such as call_builtin_trap.  */
 
 tree
-break_out_calls (tree exp)
+force_target_expr (tree type, tree init)
 {
-  register tree t1, t2 = NULL_TREE;
-  register enum tree_code code;
-  register int changed = 0;
-  register int i;
-
-  if (exp == NULL_TREE)
-    return exp;
-
-  code = TREE_CODE (exp);
-
-  if (code == CALL_EXPR)
-    return copy_node (exp);
-
-  /* Don't try and defeat a save_expr, as it should only be done once.  */
-    if (code == SAVE_EXPR)
-       return exp;
-
-  switch (TREE_CODE_CLASS (code))
-    {
-    default:
-      abort ();
-
-    case 'c':  /* a constant */
-    case 't':  /* a type node */
-    case 'x':  /* something random, like an identifier or an ERROR_MARK.  */
-      return exp;
-
-    case 'd':  /* A decl node */
-      return exp;
-
-    case 'b':  /* A block node */
-      {
-       /* Don't know how to handle these correctly yet.   Must do a
-          break_out_calls on all DECL_INITIAL values for local variables,
-          and also break_out_calls on all sub-blocks and sub-statements.  */
-       abort ();
-      }
-      return exp;
+  tree slot;
 
-    case 'e':  /* an expression */
-    case 'r':  /* a reference */
-    case 's':  /* an expression with side effects */
-      for (i = TREE_CODE_LENGTH (code) - 1; i >= 0; i--)
-       {
-         t1 = break_out_calls (TREE_OPERAND (exp, i));
-         if (t1 != TREE_OPERAND (exp, i))
-           {
-             exp = copy_node (exp);
-             TREE_OPERAND (exp, i) = t1;
-           }
-       }
-      return exp;
-
-    case '<':  /* a comparison expression */
-    case '2':  /* a binary arithmetic expression */
-      t2 = break_out_calls (TREE_OPERAND (exp, 1));
-      if (t2 != TREE_OPERAND (exp, 1))
-       changed = 1;
-    case '1':  /* a unary arithmetic expression */
-      t1 = break_out_calls (TREE_OPERAND (exp, 0));
-      if (t1 != TREE_OPERAND (exp, 0))
-       changed = 1;
-      if (changed)
-       {
-         if (TREE_CODE_LENGTH (code) == 1)
-           return build1 (code, TREE_TYPE (exp), t1);
-         else
-           return build (code, TREE_TYPE (exp), t1, t2);
-       }
-      return exp;
-    }
+  my_friendly_assert (!VOID_TYPE_P (type), 20040130);
 
+  slot = build_local_temp (type);
+  return build_target_expr (slot, init);
 }
-\f
-/* Construct, lay out and return the type of methods belonging to class
-   BASETYPE and whose arguments are described by ARGTYPES and whose values
-   are described by RETTYPE.  If each type exists already, reuse it.  */
+
+/* Like build_target_expr_with_type, but use the type of INIT.  */
 
 tree
-build_cplus_method_type (tree basetype, tree rettype, tree argtypes)
+get_target_expr (tree init)
 {
-  register tree t;
-  tree ptype;
-  int hashcode;
-
-  /* Make a node of the sort we want.  */
-  t = make_node (METHOD_TYPE);
-
-  TYPE_METHOD_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype);
-  TREE_TYPE (t) = rettype;
-  ptype = build_pointer_type (basetype);
-
-  /* The actual arglist for this function includes a "hidden" argument
-     which is "this".  Put it into the list of argument types.  */
-  argtypes = tree_cons (NULL_TREE, ptype, argtypes);
-  TYPE_ARG_TYPES (t) = argtypes;
-  TREE_SIDE_EFFECTS (argtypes) = 1;  /* Mark first argtype as "artificial".  */
-
-  /* If we already have such a type, use the old one and free this one.
-     Note that it also frees up the above cons cell if found.  */
-  hashcode = TYPE_HASH (basetype) + TYPE_HASH (rettype) +
-    type_hash_list (argtypes);
-
-  t = type_hash_canon (hashcode, t);
-
-  if (!COMPLETE_TYPE_P (t))
-    layout_type (t);
-
-  return t;
+  return build_target_expr_with_type (init, TREE_TYPE (init));
 }
 
+\f
 static tree
 build_cplus_array_type_1 (tree elt_type, tree index_type)
 {
@@ -490,14 +369,9 @@ build_cplus_array_type_1 (tree elt_type, tree index_type)
   if (elt_type == error_mark_node || index_type == error_mark_node)
     return error_mark_node;
 
-  /* Don't do the minimal thing just because processing_template_decl is
-     set; we want to give string constants the right type immediately, so
-     we don't have to fix them up at instantiation time.  */
-  if ((processing_template_decl
-       && index_type && TYPE_MAX_VALUE (index_type)
-       && TREE_CODE (TYPE_MAX_VALUE (index_type)) != INTEGER_CST)
-      || uses_template_parms (elt_type) 
-      || (index_type && uses_template_parms (index_type)))
+  if (dependent_type_p (elt_type)
+      || (index_type
+         && value_dependent_expression_p (TYPE_MAX_VALUE (index_type))))
     {
       t = make_node (ARRAY_TYPE);
       TREE_TYPE (t) = elt_type;
@@ -520,16 +394,14 @@ build_cplus_array_type (tree elt_type, tree index_type)
 {
   tree t;
   int type_quals = cp_type_quals (elt_type);
-  int cv_quals = type_quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE);
-  int other_quals = type_quals & ~(TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE);
 
-  if (cv_quals)
-    elt_type = cp_build_qualified_type (elt_type, other_quals);
+  if (type_quals != TYPE_UNQUALIFIED)
+    elt_type = cp_build_qualified_type (elt_type, TYPE_UNQUALIFIED);
 
   t = build_cplus_array_type_1 (elt_type, index_type);
 
-  if (cv_quals)
-    t = cp_build_qualified_type (t, cv_quals);
+  if (type_quals != TYPE_UNQUALIFIED)
+    t = cp_build_qualified_type (t, type_quals);
 
   return t;
 }
@@ -551,7 +423,7 @@ build_cplus_array_type (tree elt_type, tree index_type)
    via a typedef or template type argument. [dcl.ref] No such
    dispensation is provided for qualifying a function type.  [dcl.fct]
    DR 295 queries this and the proposed resolution brings it into line
-   with qualifiying a reference.  We implement the DR.  We also behave
+   with qualifying a reference.  We implement the DR.  We also behave
    in a similar manner for restricting non-pointer types.  */
  
 tree
@@ -573,54 +445,6 @@ cp_build_qualified_type_real (tree type,
   if (type_quals == cp_type_quals (type))
     return type;
 
-  /* A reference, fucntion or method type shall not be cv qualified.
-     [dcl.ref], [dct.fct]  */
-  if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)
-      && (TREE_CODE (type) == REFERENCE_TYPE
-         || TREE_CODE (type) == FUNCTION_TYPE
-         || TREE_CODE (type) == METHOD_TYPE))
-    {
-      bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
-      if (TREE_CODE (type) != REFERENCE_TYPE)
-       bad_func_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
-      type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
-    }
-  
-  /* A restrict-qualified type must be a pointer (or reference)
-     to object or incomplete type.  */
-  if ((type_quals & TYPE_QUAL_RESTRICT)
-      && TREE_CODE (type) != TEMPLATE_TYPE_PARM
-      && TREE_CODE (type) != TYPENAME_TYPE
-      && !POINTER_TYPE_P (type))
-    {
-      bad_quals |= TYPE_QUAL_RESTRICT;
-      type_quals &= ~TYPE_QUAL_RESTRICT;
-    }
-
-  if (bad_quals == TYPE_UNQUALIFIED)
-    /*OK*/;
-  else if (!(complain & (tf_error | tf_ignore_bad_quals)))
-    return error_mark_node;
-  else if (bad_func_quals && !(complain & tf_error))
-    return error_mark_node;
-  else
-    {
-      if (complain & tf_ignore_bad_quals)
-       /* We're not going to warn about constifying things that can't
-          be constified.  */
-       bad_quals &= ~TYPE_QUAL_CONST;
-      bad_quals |= bad_func_quals;
-      if (bad_quals)
-       {
-         tree bad_type = build_qualified_type (ptr_type_node, bad_quals);
-         if (!(complain & tf_ignore_bad_quals)
-             || bad_func_quals)
-           error ("`%V' qualifiers cannot be applied to `%T'",
-                  bad_type, type);
-       }
-    }
-  
   if (TREE_CODE (type) == ARRAY_TYPE)
     {
       /* In C++, the qualification really applies to the array element
@@ -675,6 +499,54 @@ cp_build_qualified_type_real (tree type,
       return build_ptrmemfunc_type (t);
     }
   
+  /* A reference, function or method type shall not be cv qualified.
+     [dcl.ref], [dct.fct]  */
+  if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)
+      && (TREE_CODE (type) == REFERENCE_TYPE
+         || TREE_CODE (type) == FUNCTION_TYPE
+         || TREE_CODE (type) == METHOD_TYPE))
+    {
+      bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+      if (TREE_CODE (type) != REFERENCE_TYPE)
+       bad_func_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+      type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+    }
+  
+  /* A restrict-qualified type must be a pointer (or reference)
+     to object or incomplete type.  */
+  if ((type_quals & TYPE_QUAL_RESTRICT)
+      && TREE_CODE (type) != TEMPLATE_TYPE_PARM
+      && TREE_CODE (type) != TYPENAME_TYPE
+      && !POINTER_TYPE_P (type))
+    {
+      bad_quals |= TYPE_QUAL_RESTRICT;
+      type_quals &= ~TYPE_QUAL_RESTRICT;
+    }
+
+  if (bad_quals == TYPE_UNQUALIFIED)
+    /*OK*/;
+  else if (!(complain & (tf_error | tf_ignore_bad_quals)))
+    return error_mark_node;
+  else if (bad_func_quals && !(complain & tf_error))
+    return error_mark_node;
+  else
+    {
+      if (complain & tf_ignore_bad_quals)
+       /* We're not going to warn about constifying things that can't
+          be constified.  */
+       bad_quals &= ~TYPE_QUAL_CONST;
+      bad_quals |= bad_func_quals;
+      if (bad_quals)
+       {
+         tree bad_type = build_qualified_type (ptr_type_node, bad_quals);
+         if (!(complain & tf_ignore_bad_quals)
+             || bad_func_quals)
+           error ("`%V' qualifiers cannot be applied to `%T'",
+                  bad_type, type);
+       }
+    }
+  
   /* Retrieve (or create) the appropriately qualified variant.  */
   result = build_qualified_type (type, type_quals);
 
@@ -852,7 +724,7 @@ tree
 hash_tree_cons (tree purpose, tree value, tree chain)
 {
   int hashcode = 0;
-  PTR* slot;
+  void **slot;
   struct list_proxy proxy;
 
   /* Hash the list node.  */
@@ -867,7 +739,7 @@ hash_tree_cons (tree purpose, tree value, tree chain)
                                   INSERT);
   /* If not, create a new node.  */
   if (!*slot)
-    *slot = (PTR) tree_cons (purpose, value, chain);
+    *slot = tree_cons (purpose, value, chain);
   return *slot;
 }
 
@@ -1064,13 +936,6 @@ build_overload (tree decl, tree chain)
   return ovl_cons (decl, chain);
 }
 
-int
-is_aggr_type_2 (tree t1, tree t2)
-{
-  if (TREE_CODE (t1) != TREE_CODE (t2))
-    return 0;
-  return IS_AGGR_TYPE (t1) && IS_AGGR_TYPE (t2);
-}
 \f
 #define PRINT_RING_SIZE 4
 
@@ -1425,18 +1290,15 @@ break_out_target_exprs (tree t)
   return t;
 }
 
-/* Obstack used for allocating nodes in template function and variable
-   definitions.  */
-
-/* Similar to `build_nt', except that we set TREE_COMPLEXITY to be the
-   current line number.  */
+/* Similar to `build_nt', but for template definitions of dependent
+   expressions  */
 
 tree
 build_min_nt (enum tree_code code, ...)
 {
-  register tree t;
-  register int length;
-  register int i;
+  tree t;
+  int length;
+  int i;
   va_list p;
 
   va_start (p, code);
@@ -1455,15 +1317,14 @@ build_min_nt (enum tree_code code, ...)
   return t;
 }
 
-/* Similar to `build', except we set TREE_COMPLEXITY to the current
-   line-number.  */
+/* Similar to `build', but for template definitions.  */
 
 tree
 build_min (enum tree_code code, tree tt, ...)
 {
-  register tree t;
-  register int length;
-  register int i;
+  tree t;
+  int length;
+  int i;
   va_list p;
 
   va_start (p, tt);
@@ -1477,12 +1338,49 @@ build_min (enum tree_code code, tree tt, ...)
     {
       tree x = va_arg (p, tree);
       TREE_OPERAND (t, i) = x;
+      if (x && TREE_SIDE_EFFECTS (x))
+       TREE_SIDE_EFFECTS (t) = 1;
     }
 
   va_end (p);
   return t;
 }
 
+/* Similar to `build', but for template definitions of non-dependent
+   expressions. NON_DEP is the non-dependent expression that has been
+   built.  */
+
+tree
+build_min_non_dep (enum tree_code code, tree non_dep, ...)
+{
+  tree t;
+  int length;
+  int i;
+  va_list p;
+
+  va_start (p, non_dep);
+
+  t = make_node (code);
+  length = TREE_CODE_LENGTH (code);
+  TREE_TYPE (t) = TREE_TYPE (non_dep);
+  TREE_COMPLEXITY (t) = input_line;
+  TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (non_dep);
+
+  for (i = 0; i < length; i++)
+    {
+      tree x = va_arg (p, tree);
+      TREE_OPERAND (t, i) = x;
+    }
+
+  if (code == COMPOUND_EXPR && TREE_CODE (non_dep) != COMPOUND_EXPR)
+    /* This should not be considered a COMPOUND_EXPR, because it
+       resolves to an overload.  */
+    COMPOUND_EXPR_OVERLOADED (t) = 1;
+  
+  va_end (p);
+  return t;
+}
+
 /* Returns an INTEGER_CST (of type `int') corresponding to I.
    Multiple calls with the same value of I may or may not yield the
    same node; therefore, callers should never modify the node
@@ -1552,38 +1450,35 @@ decl_namespace_context (tree decl)
 }
 
 /* Return truthvalue of whether T1 is the same tree structure as T2.
-   Return 1 if they are the same.
-   Return 0 if they are understandably different.
-   Return -1 if either contains tree structure not understood by
-   this function.  */
+   Return 1 if they are the same. Return 0 if they are different.  */
 
-int
+bool
 cp_tree_equal (tree t1, tree t2)
 {
-  register enum tree_code code1, code2;
-  int cmp;
+  enum tree_code code1, code2;
 
   if (t1 == t2)
-    return 1;
-  if (t1 == 0 || t2 == 0)
-    return 0;
-
-  code1 = TREE_CODE (t1);
-  code2 = TREE_CODE (t2);
-
-  if (code1 == NOP_EXPR || code1 == CONVERT_EXPR || code1 == NON_LVALUE_EXPR)
-    {
-      if (code2 == NOP_EXPR || code2 == CONVERT_EXPR || code2 == NON_LVALUE_EXPR)
-       return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
-      else
-       return cp_tree_equal (TREE_OPERAND (t1, 0), t2);
-    }
-  else if (code2 == NOP_EXPR || code2 == CONVERT_EXPR
-          || code2 == NON_LVALUE_EXPR)
-    return cp_tree_equal (t1, TREE_OPERAND (t2, 0));
-
+    return true;
+  if (!t1 || !t2)
+    return false;
+
+  for (code1 = TREE_CODE (t1);
+       code1 == NOP_EXPR || code1 == CONVERT_EXPR
+        || code1 == NON_LVALUE_EXPR;
+       code1 = TREE_CODE (t1))
+    t1 = TREE_OPERAND (t1, 0);
+  for (code2 = TREE_CODE (t2);
+       code2 == NOP_EXPR || code2 == CONVERT_EXPR
+        || code1 == NON_LVALUE_EXPR;
+       code2 = TREE_CODE (t2))
+    t2 = TREE_OPERAND (t2, 0);
+
+  /* They might have become equal now.  */
+  if (t1 == t2)
+    return true;
+  
   if (code1 != code2)
-    return 0;
+    return false;
 
   switch (code1)
     {
@@ -1597,7 +1492,7 @@ cp_tree_equal (tree t1, tree t2)
     case STRING_CST:
       return TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2)
        && !memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2),
-                 TREE_STRING_LENGTH (t1));
+                   TREE_STRING_LENGTH (t1));
 
     case CONSTRUCTOR:
       /* We need to do this when determining whether or not two
@@ -1606,61 +1501,62 @@ cp_tree_equal (tree t1, tree t2)
       if (!(same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
            /* The first operand is RTL.  */
            && TREE_OPERAND (t1, 0) == TREE_OPERAND (t2, 0)))
-       return 0;
+       return false;
       return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
 
     case TREE_LIST:
-      cmp = cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2));
-      if (cmp <= 0)
-       return cmp;
-      cmp = cp_tree_equal (TREE_VALUE (t1), TREE_VALUE (t2));
-      if (cmp <= 0)
-       return cmp;
+      if (!cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2)))
+       return false;
+      if (!cp_tree_equal (TREE_VALUE (t1), TREE_VALUE (t2)))
+       return false;
       return cp_tree_equal (TREE_CHAIN (t1), TREE_CHAIN (t2));
 
     case SAVE_EXPR:
       return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
 
     case CALL_EXPR:
-      cmp = cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
-      if (cmp <= 0)
-       return cmp;
-      return simple_cst_list_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
-
-    case TARGET_EXPR:
-      /* Special case: if either target is an unallocated VAR_DECL,
-        it means that it's going to be unified with whatever the
-        TARGET_EXPR is really supposed to initialize, so treat it
-        as being equivalent to anything.  */
-      if ((TREE_CODE (TREE_OPERAND (t1, 0)) == VAR_DECL
-          && DECL_NAME (TREE_OPERAND (t1, 0)) == NULL_TREE
-          && !DECL_RTL_SET_P (TREE_OPERAND (t1, 0)))
-         || (TREE_CODE (TREE_OPERAND (t2, 0)) == VAR_DECL
-             && DECL_NAME (TREE_OPERAND (t2, 0)) == NULL_TREE
-             && !DECL_RTL_SET_P (TREE_OPERAND (t2, 0))))
-       cmp = 1;
-      else
-       cmp = cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
-      if (cmp <= 0)
-       return cmp;
+      if (!cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)))
+       return false;
       return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
 
+    case TARGET_EXPR:
+      {
+       tree o1 = TREE_OPERAND (t1, 0);
+       tree o2 = TREE_OPERAND (t2, 0);
+       
+       /* Special case: if either target is an unallocated VAR_DECL,
+          it means that it's going to be unified with whatever the
+          TARGET_EXPR is really supposed to initialize, so treat it
+          as being equivalent to anything.  */
+       if (TREE_CODE (o1) == VAR_DECL && DECL_NAME (o1) == NULL_TREE
+           && !DECL_RTL_SET_P (o1))
+         /*Nop*/;
+       else if (TREE_CODE (o2) == VAR_DECL && DECL_NAME (o2) == NULL_TREE
+                && !DECL_RTL_SET_P (o2))
+         /*Nop*/;
+       else if (!cp_tree_equal (o1, o2))
+         return false;
+      
+       return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
+      }
+      
     case WITH_CLEANUP_EXPR:
-      cmp = cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
-      if (cmp <= 0)
-       return cmp;
+      if (!cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)))
+       return false;
       return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t1, 1));
 
     case COMPONENT_REF:
-      if (TREE_OPERAND (t1, 1) == TREE_OPERAND (t2, 1))
-       return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
-      return 0;
+      if (TREE_OPERAND (t1, 1) != TREE_OPERAND (t2, 1))
+       return false;
+      return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
 
     case VAR_DECL:
     case PARM_DECL:
     case CONST_DECL:
     case FUNCTION_DECL:
-      return 0;
+    case TEMPLATE_DECL:
+    case IDENTIFIER_NODE:
+      return false;
 
     case TEMPLATE_PARM_INDEX:
       return (TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2)
@@ -1668,19 +1564,51 @@ cp_tree_equal (tree t1, tree t2)
              && same_type_p (TREE_TYPE (TEMPLATE_PARM_DECL (t1)),
                              TREE_TYPE (TEMPLATE_PARM_DECL (t2))));
 
+    case TEMPLATE_ID_EXPR:
+      {
+       unsigned ix;
+       tree vec1, vec2;
+       
+       if (!cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)))
+         return false;
+       vec1 = TREE_OPERAND (t1, 1);
+       vec2 = TREE_OPERAND (t2, 1);
+
+       if (!vec1 || !vec2)
+         return !vec1 && !vec2;
+       
+       if (TREE_VEC_LENGTH (vec1) != TREE_VEC_LENGTH (vec2))
+         return false;
+
+       for (ix = TREE_VEC_LENGTH (vec1); ix--;)
+         if (!cp_tree_equal (TREE_VEC_ELT (vec1, ix),
+                             TREE_VEC_ELT (vec2, ix)))
+           return false;
+       
+       return true;
+      }
+      
     case SIZEOF_EXPR:
     case ALIGNOF_EXPR:
-      if (TREE_CODE (TREE_OPERAND (t1, 0)) != TREE_CODE (TREE_OPERAND (t2, 0)))
-       return 0;
-      if (TYPE_P (TREE_OPERAND (t1, 0)))
-       return same_type_p (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
-      break;
-
+      {
+       tree o1 = TREE_OPERAND (t1, 0);
+       tree o2 = TREE_OPERAND (t2, 0);
+       
+       if (TREE_CODE (o1) != TREE_CODE (o2))
+         return false;
+       if (TYPE_P (o1))
+         return same_type_p (o1, o2);
+       else
+         return cp_tree_equal (o1, o2);
+      }
+      
     case PTRMEM_CST:
       /* Two pointer-to-members are the same if they point to the same
         field or function in the same class.  */
-      return (PTRMEM_CST_MEMBER (t1) == PTRMEM_CST_MEMBER (t2)
-             && same_type_p (PTRMEM_CST_CLASS (t1), PTRMEM_CST_CLASS (t2)));
+      if (PTRMEM_CST_MEMBER (t1) != PTRMEM_CST_MEMBER (t2))
+       return false;
+
+      return same_type_p (PTRMEM_CST_CLASS (t1), PTRMEM_CST_CLASS (t2));
 
     default:
       break;
@@ -1697,21 +1625,19 @@ cp_tree_equal (tree t1, tree t2)
       {
        int i;
        
-       cmp = 1;
        for (i = 0; i < TREE_CODE_LENGTH (code1); ++i)
-         {
-           cmp = cp_tree_equal (TREE_OPERAND (t1, i), TREE_OPERAND (t2, i));
-           if (cmp <= 0)
-             return cmp;
-         }
-       return cmp;
+         if (!cp_tree_equal (TREE_OPERAND (t1, i), TREE_OPERAND (t2, i)))
+           return false;
+       
+       return true;
       }
     
-      case 't':
-       return same_type_p (t1, t2) ? 1 : 0;
+    case 't':
+      return same_type_p (t1, t2);
     }
 
-  return -1;
+  my_friendly_assert (0, 20030617);
+  return false;
 }
 
 /* Build a wrapper around a 'struct z_candidate' so we can use it as a
@@ -1743,8 +1669,11 @@ tree
 error_type (tree arg)
 {
   tree type = TREE_TYPE (arg);
+  
   if (TREE_CODE (type) == ARRAY_TYPE)
     ;
+  else if (TREE_CODE (type) == ERROR_MARK)
+    ;
   else if (real_lvalue_p (arg))
     type = build_reference_type (lvalue_type (arg));
   else if (IS_AGGR_TYPE (type))
@@ -1847,10 +1776,8 @@ pod_type_p (tree t)
     return 1;
   if (TYPE_PTR_P (t))
     return 1; /* pointer to non-member */
-  if (TYPE_PTRMEM_P (t))
-    return 1; /* pointer to member object */
-  if (TYPE_PTRMEMFUNC_P (t))
-    return 1; /* pointer to member function */
+  if (TYPE_PTR_TO_MEMBER_P (t))
+    return 1; /* pointer to member */
   
   if (! CLASS_TYPE_P (t))
     return 0; /* other non-class type (reference or function) */
@@ -2070,7 +1997,7 @@ cp_walk_subtrees (tree* tp,
     case TYPENAME_TYPE:
     case TYPEOF_TYPE:
     case BASELINK:
-      /* None of thse have subtrees other than those already walked
+      /* None of these have subtrees other than those already walked
          above.  */
       *walk_subtrees_p = 0;
       break;
@@ -2123,7 +2050,9 @@ cp_cannot_inline_tree_fn (tree* fnp)
       if (!DECL_INLINE (DECL_TEMPLATE_RESULT 
                        (template_for_substitution (fn))))
        return 1;
+
       fn = *fnp = instantiate_decl (fn, /*defer_ok=*/0);
+
       if (TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn)))
        return 1;
     }
@@ -2243,7 +2172,10 @@ cp_copy_res_decl_for_inlining (tree result,
          /* We have a named return value; copy the name and source
             position so we can get reasonable debugging information, and
             register the return variable as its equivalent.  */
-         if (TREE_CODE (var) == VAR_DECL)
+         if (TREE_CODE (var) == VAR_DECL
+             /* But not if we're initializing a variable from the
+                enclosing function which already has its own name.  */
+             && DECL_NAME (var) == NULL_TREE)
            {
              DECL_NAME (var) = DECL_NAME (nrv);
              DECL_SOURCE_LOCATION (var) = DECL_SOURCE_LOCATION (nrv);
@@ -2263,28 +2195,6 @@ cp_copy_res_decl_for_inlining (tree result,
   return var;
 }
 
-/* Record that we're about to start inlining FN, and return nonzero if
-   that's OK.  Used for lang_hooks.tree_inlining.start_inlining.  */
-
-int
-cp_start_inlining (tree fn)
-{
-  if (DECL_TEMPLATE_INSTANTIATION (fn))
-    return push_tinst_level (fn);
-  else
-    return 1;
-}
-
-/* Record that we're done inlining FN.  Used for
-   lang_hooks.tree_inlining.end_inlining.  */
-
-void
-cp_end_inlining (tree fn ATTRIBUTE_UNUSED )
-{
-  if (DECL_TEMPLATE_INSTANTIATION (fn))
-    pop_tinst_level ();
-}
-
 /* Initialize tree.c.  */
 
 void