OSDN Git Service

Rename instantiate_type_flags to tsubst_flags_t & expand use.
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 7 Feb 2002 20:51:15 +0000 (20:51 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 7 Feb 2002 20:51:15 +0000 (20:51 +0000)
* cp-tree.h (instantiate_type_flags): Rename to ...
(tsubst_flags_t): ... here. Rename itf_complain to tf_error,
add tf_warning flag.
(instantiate_type): Adjust prototype.
(tsubst, tsubst_expr, tsubst_copy, lookup_template_class,
do_type_instantiation, cp_build_qualified_type_real): Likewise.
cp_build_qualified_type: Adjust.
* class.c (instantiate_type): Adjust parameter. Rename itf_* to
tf_*.
* call.c (standard_conversion): Rename itf_* to tf_*.
(reference_binding): Likewise.
(convert_like_real): Likewise.
* cvt.c (cp_convert_to_pointer): Likewise.
(convert_to_reference): Likewise.
* decl.c (lookup_namespace_name): Use tf_* flags.
(make_typename_type): Likewise.
(grokdeclarator): Likewise.
* pt.c (convert_nontype_argument): Adjust COMPLAIN usage.
(coerce_template_template_parms, convert_template_argument,
coerce_template_parms, maybe_get_template_decl_from_type_decl,
lookup_template_class, tsubst_friend_function, tsubst_friend_class,
instantiate_class_template, tsubst_template_arg_vector,
tsubst_template_parms, tsubst_aggr_type, tsubst_default_argument,
tsubst_decl, tsubst_arg_types, tsubst_function_type,
tsubst_call_declarator_parms, tsubst, tsubst_copy, tsubst_expr,
instantiate_template, fn_type_unification,
resolve_overloaded_unification, verify_class_unification,
unify, get_bindings_real, do_type_instantiation,
regenerate_decl_from_template, instantiate_decl,
tsubst_initializer_list, tsubst_enum,
get_mostly_instantiated_function_type,
invalid_nontype_parm_type_p): Likewise.
* tree.c (cp_build_qualified_type_real): Likewise.
* typeck.c (build_binary_op): Rename itf_* to tf_*.
(build_ptrmemfunc): Likewise.
(convert_for_assignment): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@49591 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/decl.c
gcc/cp/pt.c
gcc/cp/tree.c
gcc/cp/typeck.c

index f443253..ad7dd54 100644 (file)
@@ -1,5 +1,45 @@
 2002-02-07  Nathan Sidwell  <nathan@codesourcery.com>
 
+       Rename instantiate_type_flags to tsubst_flags_t & expand use.
+       * cp-tree.h (instantiate_type_flags): Rename to ...
+       (tsubst_flags_t): ... here. Rename itf_complain to tf_error,
+       add tf_warning flag.
+       (instantiate_type): Adjust prototype.
+       (tsubst, tsubst_expr, tsubst_copy, lookup_template_class,
+       do_type_instantiation, cp_build_qualified_type_real): Likewise.
+       cp_build_qualified_type: Adjust.
+       * class.c (instantiate_type): Adjust parameter. Rename itf_* to
+       tf_*.
+       * call.c (standard_conversion): Rename itf_* to tf_*.
+       (reference_binding): Likewise.
+       (convert_like_real): Likewise.
+       * cvt.c (cp_convert_to_pointer): Likewise.
+       (convert_to_reference): Likewise.
+       * decl.c (lookup_namespace_name): Use tf_* flags.
+       (make_typename_type): Likewise.
+       (grokdeclarator): Likewise.
+       * pt.c (convert_nontype_argument): Adjust COMPLAIN usage.
+       (coerce_template_template_parms, convert_template_argument,
+       coerce_template_parms, maybe_get_template_decl_from_type_decl,
+       lookup_template_class, tsubst_friend_function, tsubst_friend_class,
+       instantiate_class_template, tsubst_template_arg_vector, 
+       tsubst_template_parms, tsubst_aggr_type, tsubst_default_argument, 
+       tsubst_decl, tsubst_arg_types, tsubst_function_type,
+       tsubst_call_declarator_parms, tsubst, tsubst_copy, tsubst_expr, 
+       instantiate_template, fn_type_unification,
+       resolve_overloaded_unification, verify_class_unification, 
+       unify, get_bindings_real, do_type_instantiation, 
+       regenerate_decl_from_template, instantiate_decl, 
+       tsubst_initializer_list, tsubst_enum,
+       get_mostly_instantiated_function_type,
+       invalid_nontype_parm_type_p): Likewise.
+       * tree.c (cp_build_qualified_type_real): Likewise.
+       * typeck.c (build_binary_op): Rename itf_* to tf_*.
+       (build_ptrmemfunc): Likewise.
+       (convert_for_assignment): Likewise.
+
+2002-02-07  Nathan Sidwell  <nathan@codesourcery.com>
+
        PR c++/109
        * decl.c (grokdeclarator): Allow friend declarations from
        dependant types.
index 925bd06..29e0c72 100644 (file)
@@ -705,7 +705,7 @@ standard_conversion (to, from, expr)
   if ((TYPE_PTRFN_P (to) || TYPE_PTRMEMFUNC_P (to))
       && expr && type_unknown_p (expr))
     {
-      expr = instantiate_type (to, expr, itf_none);
+      expr = instantiate_type (to, expr, tf_none);
       if (expr == error_mark_node)
        return NULL_TREE;
       from = TREE_TYPE (expr);
@@ -1108,7 +1108,7 @@ reference_binding (rto, rfrom, expr, flags)
 
   if (TREE_CODE (to) == FUNCTION_TYPE && expr && type_unknown_p (expr))
     {
-      expr = instantiate_type (to, expr, itf_none);
+      expr = instantiate_type (to, expr, tf_none);
       if (expr == error_mark_node)
        return NULL_TREE;
       from = TREE_TYPE (expr);
@@ -3864,7 +3864,7 @@ convert_like_real (convs, expr, fn, argnum, inner)
       }
     case IDENTITY_CONV:
       if (type_unknown_p (expr))
-       expr = instantiate_type (totype, expr, itf_complain);
+       expr = instantiate_type (totype, expr, tf_error | tf_warning);
       return expr;
     case AMBIG_CONV:
       /* Call build_user_type_conversion again for the error.  */
index c5e349c..4070286 100644 (file)
@@ -6043,14 +6043,14 @@ cannot resolve overloaded function `%D' based on conversion to type `%T'",
 tree
 instantiate_type (lhstype, rhs, flags)
      tree lhstype, rhs;
-     enum instantiate_type_flags flags;
+     tsubst_flags_t flags;
 {
-  int complain = (flags & itf_complain);
-  int strict = (flags & itf_no_attributes)
+  int complain = (flags & tf_error);
+  int strict = (flags & tf_no_attributes)
                ? COMPARE_NO_ATTRIBUTES : COMPARE_STRICT;
-  int allow_ptrmem = flags & itf_ptrmem_ok;
+  int allow_ptrmem = flags & tf_ptrmem_ok;
   
-  flags &= ~itf_ptrmem_ok;
+  flags &= ~tf_ptrmem_ok;
   
   if (TREE_CODE (lhstype) == UNKNOWN_TYPE)
     {
@@ -6257,7 +6257,7 @@ instantiate_type (lhstype, rhs, flags)
     case ADDR_EXPR:
     {
       if (PTRMEM_OK_P (rhs))
-        flags |= itf_ptrmem_ok;
+        flags |= tf_ptrmem_ok;
       
       return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);
     }
index 8b242e5..169d1a2 100644 (file)
@@ -3063,13 +3063,16 @@ typedef enum linkage_kind {
   lk_external              /* External linkage.  */
 } linkage_kind;
 
-/* Bitmask flags to pass to instantiate_type.  */
-typedef enum instantiate_type_flags {
-  itf_none = 0,               /* nothing special */
-  itf_complain = 1 << 0,      /* complain about errors */
-  itf_no_attributes = 1 << 1, /* ignore attributes on comparisons */
-  itf_ptrmem_ok = 1 << 2,     /* pointers to member ok (internal use) */
-} instantiate_type_flags;
+/* Bitmask flags to control type substitution.  */
+typedef enum tsubst_flags_t {
+  tf_none = 0,               /* nothing special */
+  tf_error = 1 << 0,         /* give error messages  */
+  tf_warning = 1 << 1,       /* give warnings too  */
+  tf_no_attributes = 1 << 2, /* ignore attributes on comparisons
+                               (instantiate_type use) */
+  tf_ptrmem_ok = 1 << 3      /* pointers to member ok (internal
+                               instantiate_type use) */
+} tsubst_flags_t;
 
 /* The kind of checking we can do looking in a class hierarchy. */
 typedef enum base_access {
@@ -3598,7 +3601,7 @@ extern void pop_nested_class                      PARAMS ((void));
 extern int current_lang_depth                  PARAMS ((void));
 extern void push_lang_context                  PARAMS ((tree));
 extern void pop_lang_context                   PARAMS ((void));
-extern tree instantiate_type                   PARAMS ((tree, tree, enum instantiate_type_flags));
+extern tree instantiate_type                   PARAMS ((tree, tree, tsubst_flags_t));
 extern void print_class_statistics              PARAMS ((void));
 extern void cxx_print_statistics               PARAMS ((void));
 extern void cxx_print_xnode                    PARAMS ((FILE *, tree, int));
@@ -3972,9 +3975,9 @@ extern int maybe_clone_body                     PARAMS ((tree));
 extern void init_pt                             PARAMS ((void));
 extern void check_template_shadow              PARAMS ((tree));
 extern tree get_innermost_template_args         PARAMS ((tree, int));
-extern tree tsubst                             PARAMS ((tree, tree, int, tree));
-extern tree tsubst_expr                                PARAMS ((tree, tree, int, tree));
-extern tree tsubst_copy                                PARAMS ((tree, tree, int, tree));
+extern tree tsubst                             PARAMS ((tree, tree, tsubst_flags_t, tree));
+extern tree tsubst_expr                                PARAMS ((tree, tree, tsubst_flags_t, tree));
+extern tree tsubst_copy                                PARAMS ((tree, tree, tsubst_flags_t, tree));
 extern void maybe_begin_member_template_processing PARAMS ((tree));
 extern void maybe_end_member_template_processing PARAMS ((void));
 extern tree finish_member_template_decl         PARAMS ((tree));
@@ -3992,7 +3995,7 @@ extern tree current_template_args         PARAMS ((void));
 extern tree push_template_decl                 PARAMS ((tree));
 extern tree push_template_decl_real             PARAMS ((tree, int));
 extern void redeclare_class_template            PARAMS ((tree, tree));
-extern tree lookup_template_class              PARAMS ((tree, tree, tree, tree, int, int));
+extern tree lookup_template_class              PARAMS ((tree, tree, tree, tree, int, tsubst_flags_t));
 extern tree lookup_template_function            PARAMS ((tree, tree));
 extern int uses_template_parms                 PARAMS ((tree));
 extern tree instantiate_class_template         PARAMS ((tree));
@@ -4003,7 +4006,7 @@ extern void mark_decl_instantiated                PARAMS ((tree, int));
 extern int more_specialized                    PARAMS ((tree, tree, int, int));
 extern void mark_class_instantiated            PARAMS ((tree, int));
 extern void do_decl_instantiation              PARAMS ((tree, tree, tree));
-extern void do_type_instantiation              PARAMS ((tree, tree, int));
+extern void do_type_instantiation              PARAMS ((tree, tree, tsubst_flags_t));
 extern tree instantiate_decl                   PARAMS ((tree, int));
 extern tree get_bindings                       PARAMS ((tree, tree, tree));
 extern int push_tinst_level                    PARAMS ((tree));
@@ -4262,9 +4265,9 @@ extern tree maybe_dummy_object                    PARAMS ((tree, tree *));
 extern int is_dummy_object                     PARAMS ((tree));
 extern const struct attribute_spec cp_attribute_table[];
 extern tree make_ptrmem_cst                     PARAMS ((tree, tree));
-extern tree cp_build_qualified_type_real        PARAMS ((tree, int, int));
+extern tree cp_build_qualified_type_real        PARAMS ((tree, int, tsubst_flags_t));
 #define cp_build_qualified_type(TYPE, QUALS) \
-  cp_build_qualified_type_real ((TYPE), (QUALS), /*complain=*/1)
+  cp_build_qualified_type_real ((TYPE), (QUALS), tf_error | tf_warning)
 extern tree build_shared_int_cst                PARAMS ((int));
 extern special_function_kind special_function_p PARAMS ((tree));
 extern int count_trees                          PARAMS ((tree));
index 6029e84..1d5dc90 100644 (file)
@@ -267,7 +267,7 @@ cp_convert_to_pointer (type, expr, force)
     }
 
   if (type_unknown_p (expr))
-    return instantiate_type (type, expr, itf_complain);
+    return instantiate_type (type, expr, tf_error | tf_warning);
 
   error ("cannot convert `%E' from type `%T' to type `%T'",
            expr, intype, type);
@@ -478,7 +478,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
     {
       expr = instantiate_type (type, expr, 
                               (flags & LOOKUP_COMPLAIN)
-                              ? itf_complain : itf_none);
+                              ? tf_error | tf_warning : tf_none);
       if (expr == error_mark_node)
        return error_mark_node;
 
index 6fd9890..158dc8f 100644 (file)
@@ -5491,7 +5491,7 @@ lookup_namespace_name (namespace, name)
                                         /*in_decl=*/NULL_TREE,
                                         /*context=*/NULL_TREE,
                                         /*entering_scope=*/0,
-                                        /*complain=*/1);
+                                        tf_error | tf_warning);
          else if (DECL_FUNCTION_TEMPLATE_P (val)
                   || TREE_CODE (val) == OVERLOAD)
            val = lookup_template_function (val,
@@ -5680,7 +5680,7 @@ make_typename_type (context, name, complain)
                                        TREE_OPERAND (fullname, 1),
                                        NULL_TREE, context,
                                        /*entering_scope=*/0,
-                                       /*complain=*/1);
+                                       tf_error | tf_warning);
        }
       else
        {
@@ -10906,7 +10906,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                    && uses_template_parms (current_class_type))
                  {
                    tree args = current_template_args ();
-                   type = tsubst (type, args, /*complain=*/1, NULL_TREE);
+                   type = tsubst (type, args, tf_error | tf_warning,
+                                  NULL_TREE);
                  }
 
                /* This pop_nested_class corresponds to the
index 9e5b20c..d963a79 100644 (file)
@@ -93,30 +93,32 @@ static htab_t local_specializations;
                             type with the desired type.  */
 
 static int resolve_overloaded_unification PARAMS ((tree, tree, tree, tree,
-                                                unification_kind_t, int));
+                                                  unification_kind_t, int));
 static int try_one_overload PARAMS ((tree, tree, tree, tree, tree,
-                                  unification_kind_t, int));
+                                    unification_kind_t, int));
 static int unify PARAMS ((tree, tree, tree, tree, int));
 static void add_pending_template PARAMS ((tree));
 static void reopen_tinst_level PARAMS ((tree));
 static tree classtype_mangled_name PARAMS ((tree));
-static char *mangle_class_name_for_template PARAMS ((const char *, tree, tree));
+static char *mangle_class_name_for_template PARAMS ((const char *,
+                                                    tree, tree));
 static tree tsubst_initializer_list PARAMS ((tree, tree));
 static int list_eq PARAMS ((tree, tree));
 static tree get_class_bindings PARAMS ((tree, tree, tree));
-static tree coerce_template_parms PARAMS ((tree, tree, tree, int, int));
+static tree coerce_template_parms PARAMS ((tree, tree, tree,
+                                          tsubst_flags_t, int));
 static void tsubst_enum        PARAMS ((tree, tree, tree));
 static tree add_to_template_args PARAMS ((tree, tree));
 static tree add_outermost_template_args PARAMS ((tree, tree));
 static int maybe_adjust_types_for_deduction PARAMS ((unification_kind_t, tree*,
-                                                   tree*)); 
+                                                    tree*)); 
 static int  type_unification_real PARAMS ((tree, tree, tree, tree,
-                                        int, unification_kind_t, int, int));
+                                          int, unification_kind_t, int, int));
 static void note_template_header PARAMS ((int));
 static tree maybe_fold_nontype_arg PARAMS ((tree));
 static tree convert_nontype_argument PARAMS ((tree, tree));
-static tree convert_template_argument PARAMS ((tree, tree, tree, int,
-                                             int , tree));
+static tree convert_template_argument PARAMS ((tree, tree, tree,
+                                              tsubst_flags_t, int, tree));
 static tree get_bindings_overload PARAMS ((tree, tree, tree));
 static int for_each_template_parm PARAMS ((tree, tree_fn_t, void*));
 static tree build_template_parm_index PARAMS ((int, int, int, tree, tree));
@@ -136,35 +138,36 @@ static tree get_bindings_real PARAMS ((tree, tree, tree, int, int, int));
 static int template_decl_level PARAMS ((tree));
 static tree maybe_get_template_decl_from_type_decl PARAMS ((tree));
 static int check_cv_quals_for_unify PARAMS ((int, tree, tree));
-static tree tsubst_template_arg_vector PARAMS ((tree, tree, int));
-static tree tsubst_template_parms PARAMS ((tree, tree, int));
+static tree tsubst_template_arg_vector PARAMS ((tree, tree, tsubst_flags_t));
+static tree tsubst_template_parms PARAMS ((tree, tree, tsubst_flags_t));
 static void regenerate_decl_from_template PARAMS ((tree, tree));
 static tree most_specialized PARAMS ((tree, tree, tree));
 static tree most_specialized_class PARAMS ((tree, tree));
 static int template_class_depth_real PARAMS ((tree, int));
-static tree tsubst_aggr_type PARAMS ((tree, tree, int, tree, int));
-static tree tsubst_decl PARAMS ((tree, tree, tree));
-static tree tsubst_arg_types PARAMS ((tree, tree, int, tree));
-static tree tsubst_function_type PARAMS ((tree, tree, int, tree));
+static tree tsubst_aggr_type PARAMS ((tree, tree, tsubst_flags_t, tree, int));
+static tree tsubst_decl PARAMS ((tree, tree, tree, tsubst_flags_t));
+static tree tsubst_arg_types PARAMS ((tree, tree, tsubst_flags_t, tree));
+static tree tsubst_function_type PARAMS ((tree, tree, tsubst_flags_t, tree));
 static void check_specialization_scope PARAMS ((void));
 static tree process_partial_specialization PARAMS ((tree));
 static void set_current_access_from_decl PARAMS ((tree));
 static void check_default_tmpl_args PARAMS ((tree, tree, int, int));
-static tree tsubst_call_declarator_parms PARAMS ((tree, tree, int, tree));
+static tree tsubst_call_declarator_parms PARAMS ((tree, tree,
+                                                 tsubst_flags_t, tree));
 static tree get_template_base_recursive PARAMS ((tree, tree,
-                                              tree, tree, tree, int)); 
+                                                tree, tree, tree, int)); 
 static tree get_template_base PARAMS ((tree, tree, tree, tree));
 static int verify_class_unification PARAMS ((tree, tree, tree));
 static tree try_class_unification PARAMS ((tree, tree, tree, tree));
-static int coerce_template_template_parms PARAMS ((tree, tree, int,
-                                                tree, tree));
+static int coerce_template_template_parms PARAMS ((tree, tree, tsubst_flags_t,
+                                                  tree, tree));
 static tree determine_specialization PARAMS ((tree, tree, tree *, int));
 static int template_args_equal PARAMS ((tree, tree));
 static void tsubst_default_arguments PARAMS ((tree));
 static tree for_each_template_parm_r PARAMS ((tree *, int *, void *));
 static tree copy_default_args_to_explicit_spec_1 PARAMS ((tree, tree));
 static void copy_default_args_to_explicit_spec PARAMS ((tree));
-static int invalid_nontype_parm_type_p PARAMS ((tree, int));
+static int invalid_nontype_parm_type_p PARAMS ((tree, tsubst_flags_t));
 
 /* Called once to initialize pt.c.  */
 
@@ -3013,7 +3016,7 @@ convert_nontype_argument (type, expr)
            else
              fns = expr;
 
-           fn = instantiate_type (type_pointed_to, fns, itf_none);
+           fn = instantiate_type (type_pointed_to, fns, tf_none);
 
            if (fn == error_mark_node)
              return error_mark_node;
@@ -3078,7 +3081,7 @@ convert_nontype_argument (type, expr)
               set (_over.over_).  */
            tree fn;
 
-           fn = instantiate_type (type_referred_to, expr, itf_none);
+           fn = instantiate_type (type_referred_to, expr, tf_none);
 
            if (fn == error_mark_node)
              return error_mark_node;
@@ -3147,7 +3150,7 @@ convert_nontype_argument (type, expr)
        if (TREE_CODE (expr) != ADDR_EXPR)
          return error_mark_node;
 
-       expr = instantiate_type (type, expr, itf_none);
+       expr = instantiate_type (type, expr, tf_none);
        
        if (expr == error_mark_node)
          return error_mark_node;
@@ -3188,7 +3191,7 @@ static int
 coerce_template_template_parms (parm_parms, arg_parms, complain, 
                                in_decl, outer_args)
      tree parm_parms, arg_parms;
-     int complain;
+     tsubst_flags_t complain;
      tree in_decl, outer_args;
 {
   int nparms, nargs, i;
@@ -3257,17 +3260,17 @@ coerce_template_template_parms (parm_parms, arg_parms, complain,
 
 /* Convert the indicated template ARG as necessary to match the
    indicated template PARM.  Returns the converted ARG, or
-   error_mark_node if the conversion was unsuccessful.  Error messages
-   are issued if COMPLAIN is non-zero.  This conversion is for the Ith
-   parameter in the parameter list.  ARGS is the full set of template
-   arguments deduced so far.  */
+   error_mark_node if the conversion was unsuccessful.  Error and
+   warning messages are issued under control of COMPLAIN.  This
+   conversion is for the Ith parameter in the parameter list.  ARGS is
+   the full set of template arguments deduced so far.  */
 
 static tree
 convert_template_argument (parm, arg, args, complain, i, in_decl)
      tree parm;
      tree arg;
      tree args;
-     int complain;
+     tsubst_flags_t complain;
      int i;
      tree in_decl;
 {
@@ -3331,14 +3334,16 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
       
       arg = make_typename_type (TREE_OPERAND (arg, 0),
                                TREE_OPERAND (arg, 1),
-                               complain);
+                               complain & tf_error);
+      if (TREE_CODE (arg) == TYPE_DECL)
+       arg = TREE_TYPE (arg);
       is_type = 1;
     }
   if (is_type != requires_type)
     {
       if (in_decl)
        {
-         if (complain)
+         if (complain & tf_error)
            {
              error ("type/value mismatch at argument %d in template parameter list for `%D'",
                        i + 1, in_decl);
@@ -3354,7 +3359,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
     }
   if (is_tmpl_type ^ requires_tmpl_type)
     {
-      if (in_decl && complain)
+      if (in_decl && (complain & tf_error))
        {
          error ("type/value mismatch at argument %d in template parameter list for `%D'",
                    i + 1, in_decl);
@@ -3393,7 +3398,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
                }
              else
                {
-                 if (in_decl && complain)
+                 if (in_decl && (complain & tf_error))
                    {
                      error ("type/value mismatch at argument %d in template parameter list for `%D'",
                                i + 1, in_decl);
@@ -3456,7 +3461,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
 
       if (val == NULL_TREE)
        val = error_mark_node;
-      else if (val == error_mark_node && complain)
+      else if (val == error_mark_node && (complain & tf_error))
        error ("could not convert template argument `%E' to `%T'", 
                  arg, t);
     }
@@ -3466,10 +3471,10 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
 
 /* Convert all template arguments to their appropriate types, and
    return a vector containing the innermost resulting template
-   arguments.  If any error occurs, return error_mark_node, and, if
-   COMPLAIN is non-zero, issue an error message.  Some error messages
-   are issued even if COMPLAIN is zero; for instance, if a template
-   argument is composed from a local class.
+   arguments.  If any error occurs, return error_mark_node. Error and
+   warning messages are issued under control of COMPLAIN.  Some error
+   messages are issued even if COMPLAIN is zero; for instance, if a
+   template argument is composed from a local class.
 
    If REQUIRE_ALL_ARGUMENTS is non-zero, all arguments must be
    provided in ARGLIST, or else trailing parameters must have default
@@ -3482,7 +3487,7 @@ coerce_template_parms (parms, args, in_decl,
                       require_all_arguments)
      tree parms, args;
      tree in_decl;
-     int complain;
+     tsubst_flags_t complain;
      int require_all_arguments;
 {
   int nparms, nargs, i, lost = 0;
@@ -3499,7 +3504,7 @@ coerce_template_parms (parms, args, in_decl,
          && require_all_arguments
          && TREE_PURPOSE (TREE_VEC_ELT (parms, nargs)) == NULL_TREE))
     {
-      if (complain) 
+      if (complain & tf_error
        {
          error ("wrong number of template arguments (%d, should be %d)",
                    nargs, nparms);
@@ -3831,7 +3836,7 @@ maybe_get_template_decl_from_type_decl (decl)
    If ENTERING_SCOPE is non-zero, we are about to enter the scope of
    the class we are looking up.
    
-   If COMPLAIN is non-zero, issue error messages.
+   Issue error and warning messages under control of COMPLAIN.
 
    If the template class is really a local class in a template
    function, then the FUNCTION_CONTEXT is the function in which it is
@@ -3843,7 +3848,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
      tree in_decl;
      tree context;
      int entering_scope;
-     int complain;
+     tsubst_flags_t complain;
 {
   tree template = NULL_TREE, parmlist;
   tree t;
@@ -3901,7 +3906,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
      crash. Alternatively D1 might not be a template type at all.  */
   if (! template)
     {
-      if (complain)
+      if (complain & tf_error)
         error ("`%T' is not a template", d1);
       return error_mark_node;
     }
@@ -3913,7 +3918,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
           && !DECL_TEMPLATE_PARM_P (template)
           && !PRIMARY_TEMPLATE_P (template)))
     {
-      if (complain)
+      if (complain & tf_error)
         {
           error ("non-template type `%T' used as a template", d1);
           if (in_decl)
@@ -4111,7 +4116,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
        }
       
       context = tsubst (DECL_CONTEXT (template), arglist,
-                       /*complain=*/0, in_decl);
+                       complain, in_decl);
       if (!context)
        context = global_namespace;
 
@@ -4218,7 +4223,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
                  Create the partial instantiation.
                */
               TREE_VEC_LENGTH (arglist)--;
-              found = tsubst (template, arglist, /*complain=*/0, NULL_TREE);
+              found = tsubst (template, arglist, complain, NULL_TREE);
               TREE_VEC_LENGTH (arglist)++;
             }
        }
@@ -4592,13 +4597,13 @@ tsubst_friend_function (decl, args)
          current cless with same name.  */
       push_nested_namespace (ns);
       fns = tsubst_expr (DECL_TI_TEMPLATE (decl), args,
-                         /*complain=*/1, NULL_TREE);
+                         tf_error | tf_warning, NULL_TREE);
       pop_nested_namespace (ns);
       arglist = tsubst (DECL_TI_ARGS (decl), args,
-                        /*complain=*/1, NULL_TREE);
+                        tf_error | tf_warning, NULL_TREE);
       template_id = lookup_template_function (fns, arglist);
       
-      new_friend = tsubst (decl, args, /*complain=*/1, NULL_TREE);
+      new_friend = tsubst (decl, args, tf_error | tf_warning, NULL_TREE);
       tmpl = determine_specialization (template_id, new_friend,
                                       &new_args, 
                                       /*need_member_template=*/0);
@@ -4606,7 +4611,7 @@ tsubst_friend_function (decl, args)
       goto done;
     }
 
-  new_friend = tsubst (decl, args, /*complain=*/1, NULL_TREE);
+  new_friend = tsubst (decl, args, tf_error | tf_warning, NULL_TREE);
        
   /* The NEW_FRIEND will look like an instantiation, to the
      compiler, but is not an instantiation from the point of view of
@@ -4824,7 +4829,7 @@ tsubst_friend_class (friend_tmpl, args)
         at.  */
       tree parms 
        = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_tmpl),
-                                args, /*complain=*/1);
+                                args, tf_error | tf_warning);
       if (!parms)
         return error_mark_node;
       redeclare_class_template (TREE_TYPE (tmpl), parms);
@@ -4835,7 +4840,7 @@ tsubst_friend_class (friend_tmpl, args)
       /* The friend template has not already been declared.  In this
         case, the instantiation of the template class will cause the
         injection of this template into the global scope.  */
-      tmpl = tsubst (friend_tmpl, args, /*complain=*/1, NULL_TREE);
+      tmpl = tsubst (friend_tmpl, args, tf_error | tf_warning, NULL_TREE);
 
       /* The new TMPL is not an instantiation of anything, so we
         forget its origins.  We don't reset CLASSTYPE_TI_TEMPLATE for
@@ -5062,8 +5067,7 @@ instantiate_class_template (type)
          pbase = TREE_VEC_ELT (pbases, i);
 
          /* Substitute to figure out the base class.  */
-         base = tsubst (BINFO_TYPE (pbase), args, 
-                        /*complain=*/1, NULL_TREE);
+         base = tsubst (BINFO_TYPE (pbase), args, tf_error, NULL_TREE);
          if (base == error_mark_node)
            continue;
 
@@ -5117,7 +5121,7 @@ instantiate_class_template (type)
       tree name = TYPE_IDENTIFIER (tag);
       tree newtag;
 
-      newtag = tsubst (tag, args, /*complain=*/1, NULL_TREE);
+      newtag = tsubst (tag, args, tf_error, NULL_TREE);
       my_friendly_assert (newtag != error_mark_node, 20010206);
       if (TREE_CODE (newtag) != ENUMERAL_TYPE)
        {
@@ -5155,14 +5159,14 @@ instantiate_class_template (type)
        lineno = DECL_SOURCE_LINE (t);
        input_filename = DECL_SOURCE_FILE (t);
 
-       r = tsubst (t, args, /*complain=*/1, NULL_TREE);
+       r = tsubst (t, args, tf_error | tf_warning, NULL_TREE);
        if (TREE_CODE (r) == VAR_DECL)
          {
            tree init;
 
            if (DECL_INITIALIZED_IN_CLASS_P (r))
              init = tsubst_expr (DECL_INITIAL (t), args,
-                                 /*complain=*/1, NULL_TREE);
+                                 tf_error | tf_warning, NULL_TREE);
            else
              init = NULL_TREE;
 
@@ -5190,7 +5194,7 @@ instantiate_class_template (type)
      for this instantiation.  */
   for (t = TYPE_METHODS (pattern); t; t = TREE_CHAIN (t))
     {
-      tree r = tsubst (t, args, /*complain=*/1, NULL_TREE);
+      tree r = tsubst (t, args, tf_error, NULL_TREE);
       set_current_access_from_decl (r);
       grok_special_member_properties (r);
       finish_member_declaration (r);
@@ -5225,8 +5229,8 @@ instantiate_class_template (type)
       if (TREE_CODE (friend_type) == TEMPLATE_DECL)
        new_friend_type = tsubst_friend_class (friend_type, args);
       else if (uses_template_parms (friend_type))
-       new_friend_type = tsubst (friend_type, args, /*complain=*/1,
-                                 NULL_TREE);
+       new_friend_type = tsubst (friend_type, args,
+                                 tf_error | tf_warning, NULL_TREE);
       else 
        {
          tree ns = decl_namespace_context (TYPE_MAIN_DECL (friend_type));
@@ -5350,7 +5354,7 @@ static tree
 tsubst_template_arg_vector (t, args, complain)
      tree t;
      tree args;
-     int complain;
+     tsubst_flags_t complain;
 {
   int len = TREE_VEC_LENGTH (t), need_new = 0, i;
   tree *elts = (tree *) alloca (len * sizeof (tree));
@@ -5396,7 +5400,7 @@ static tree
 tsubst_template_parms (parms, args, complain)
      tree parms;
      tree args;
-     int complain;
+     tsubst_flags_t complain;
 {
   tree r = NULL_TREE;
   tree* new_parms;
@@ -5443,7 +5447,7 @@ static tree
 tsubst_aggr_type (t, args, complain, in_decl, entering_scope)
      tree t;
      tree args;
-     int complain;
+     tsubst_flags_t complain;
      tree in_decl;
      int entering_scope;
 {
@@ -5491,8 +5495,7 @@ tsubst_aggr_type (t, args, complain, in_decl, entering_scope)
          r = lookup_template_class (t, argvec, in_decl, context,
                                     entering_scope, complain);
 
-         return cp_build_qualified_type_real (r, TYPE_QUALS (t),
-                                              complain);
+         return cp_build_qualified_type_real (r, TYPE_QUALS (t), complain);
        }
       else 
        /* This is not a template type, so there's nothing to do.  */
@@ -5527,7 +5530,8 @@ tsubst_default_argument (fn, type, arg)
   if (DECL_CLASS_SCOPE_P (fn))
     pushclass (DECL_CONTEXT (fn), 2);
 
-  arg = tsubst_expr (arg, DECL_TI_ARGS (fn), /*complain=*/1, NULL_TREE);
+  arg = tsubst_expr (arg, DECL_TI_ARGS (fn),
+                    tf_error | tf_warning, NULL_TREE);
   
   if (DECL_CLASS_SCOPE_P (fn))
     popclass ();
@@ -5565,19 +5569,23 @@ tsubst_default_arguments (fn)
 
 /* Substitute the ARGS into the T, which is a _DECL.  TYPE is the
    (already computed) substitution of ARGS into TREE_TYPE (T), if
-   appropriate.  Return the result of the substitution.  */
+   appropriate.  Return the result of the substitution.  Issue error
+   and warning messages under control of COMPLAIN.  */
 
 static tree
-tsubst_decl (t, args, type)
+tsubst_decl (t, args, type, complain)
      tree t;
      tree args;
      tree type;
+     tsubst_flags_t complain;
 {
   int saved_lineno;
   const char *saved_filename;
   tree r = NULL_TREE;
   tree in_decl = t;
 
+  my_friendly_assert (complain & tf_error, 20011214);
+  
   /* Set the filename and linenumber to improve error-reporting.  */
   saved_lineno = lineno;
   saved_filename = input_filename;
@@ -5606,7 +5614,7 @@ tsubst_decl (t, args, type)
            tree full_args;
            
            full_args = tsubst_template_arg_vector (tmpl_args, args,
-                                                   /*complain=*/1);
+                                                   complain);
 
            /* tsubst_template_arg_vector doesn't copy the vector if
               nothing changed.  But, *something* should have
@@ -5632,7 +5640,7 @@ tsubst_decl (t, args, type)
 
        if (is_template_template_parm)
          {
-           tree new_decl = tsubst (decl, args, /*complain=*/1, in_decl);
+           tree new_decl = tsubst (decl, args, complain, in_decl);
            DECL_TEMPLATE_RESULT (r) = new_decl;
            TREE_TYPE (r) = TREE_TYPE (new_decl);
            break;
@@ -5640,18 +5648,17 @@ tsubst_decl (t, args, type)
 
        DECL_CONTEXT (r) 
          = tsubst_aggr_type (DECL_CONTEXT (t), args, 
-                             /*complain=*/1, in_decl, 
+                             complain, in_decl, 
                              /*entering_scope=*/1); 
        DECL_VIRTUAL_CONTEXT (r) 
          = tsubst_aggr_type (DECL_VIRTUAL_CONTEXT (t), args, 
-                             /*complain=*/1, in_decl, 
+                             complain, in_decl, 
                              /*entering_scope=*/1);
        DECL_TEMPLATE_INFO (r) = build_tree_list (t, args);
 
        if (TREE_CODE (decl) == TYPE_DECL)
          {
-           tree new_type = tsubst (TREE_TYPE (t), args,
-                                   /*complain=*/1, in_decl);
+           tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
            TREE_TYPE (r) = new_type;
            CLASSTYPE_TI_TEMPLATE (new_type) = r;
            DECL_TEMPLATE_RESULT (r) = TYPE_MAIN_DECL (new_type);
@@ -5659,7 +5666,7 @@ tsubst_decl (t, args, type)
          }
        else
          {
-           tree new_decl = tsubst (decl, args, /*complain=*/1, in_decl);
+           tree new_decl = tsubst (decl, args, complain, in_decl);
 
            DECL_TEMPLATE_RESULT (r) = new_decl;
            DECL_TI_TEMPLATE (new_decl) = r;
@@ -5676,7 +5683,7 @@ tsubst_decl (t, args, type)
           outermost level of parameters. */
        DECL_TEMPLATE_PARMS (r) 
          = tsubst_template_parms (DECL_TEMPLATE_PARMS (t), args,
-                                  /*complain=*/1);
+                                  complain);
 
        if (PRIMARY_TEMPLATE_P (t))
          DECL_PRIMARY_TEMPLATE (r) = r;
@@ -5716,7 +5723,7 @@ tsubst_decl (t, args, type)
            argvec 
              = tsubst_template_arg_vector (DECL_TI_ARGS 
                                            (DECL_TEMPLATE_RESULT (gen_tmpl)),
-                                           args, /*complain=*/1); 
+                                           args, complain); 
 
            /* Check to see if we already have this specialization.  */
            spec = retrieve_specialization (gen_tmpl, argvec);
@@ -5793,7 +5800,7 @@ tsubst_decl (t, args, type)
            else
              member = 1;
            ctx = tsubst_aggr_type (DECL_CONTEXT (t), args, 
-                                   /*complain=*/1, t, 
+                                   complain, t, 
                                    /*entering_scope=*/1);
          }
        else
@@ -5801,7 +5808,7 @@ tsubst_decl (t, args, type)
            member = 0;
            ctx = DECL_CONTEXT (t);
          }
-       type = tsubst (type, args, /*complain=*/1, in_decl);
+       type = tsubst (type, args, complain, in_decl);
        if (type == error_mark_node)
          return error_mark_node;
 
@@ -5819,7 +5826,7 @@ tsubst_decl (t, args, type)
        DECL_CONTEXT (r) = ctx;
        DECL_VIRTUAL_CONTEXT (r)
          = tsubst_aggr_type (DECL_VIRTUAL_CONTEXT (t), args, 
-                             /*complain=*/1, t,
+                             complain, t,
                              /*entering_scope=*/1);
 
        if (member && DECL_CONV_FN_P (r)) 
@@ -5828,7 +5835,7 @@ tsubst_decl (t, args, type)
          DECL_NAME (r) = mangle_conv_op_name_for_type (TREE_TYPE (type));
 
        DECL_ARGUMENTS (r) = tsubst (DECL_ARGUMENTS (t), args,
-                                    /*complain=*/1, t);
+                                    complain, t);
        DECL_RESULT (r) = NULL_TREE;
 
        TREE_STATIC (r) = 0;
@@ -5844,7 +5851,7 @@ tsubst_decl (t, args, type)
        if (DECL_CLONED_FUNCTION (r))
          {
            DECL_CLONED_FUNCTION (r) = tsubst (DECL_CLONED_FUNCTION (t),
-                                              args, /*complain=*/1, t);
+                                              args, complain, t);
            TREE_CHAIN (r) = TREE_CHAIN (DECL_CLONED_FUNCTION (r));
            TREE_CHAIN (DECL_CLONED_FUNCTION (r)) = r;
          }
@@ -5883,7 +5890,7 @@ tsubst_decl (t, args, type)
          {
            *friends = copy_node (*friends);
            TREE_VALUE (*friends) = tsubst (TREE_VALUE (*friends),
-                                           args, /*complain=*/1, 
+                                           args, complain,
                                            in_decl);
          }
 
@@ -5916,7 +5923,7 @@ tsubst_decl (t, args, type)
          DECL_INITIAL (r) = TREE_TYPE (r);
        else
          DECL_INITIAL (r) = tsubst (DECL_INITIAL (r), args,
-                                    /*complain=*/1, in_decl);
+                                    complain, in_decl);
 
        DECL_CONTEXT (r) = NULL_TREE;
        if (!DECL_TEMPLATE_PARM_P (r) && PROMOTE_PROTOTYPES
@@ -5925,7 +5932,7 @@ tsubst_decl (t, args, type)
          DECL_ARG_TYPE (r) = integer_type_node;
        if (TREE_CHAIN (t))
          TREE_CHAIN (r) = tsubst (TREE_CHAIN (t), args,
-                                  /*complain=*/1, TREE_CHAIN (t));
+                                  complain, TREE_CHAIN (t));
       }
       break;
 
@@ -5938,7 +5945,7 @@ tsubst_decl (t, args, type)
        /* We don't have to set DECL_CONTEXT here; it is set by
           finish_member_declaration.  */
        DECL_INITIAL (r) = tsubst_expr (DECL_INITIAL (t), args,
-                                       /*complain=*/1, in_decl);
+                                       complain, in_decl);
        TREE_CHAIN (r) = NULL_TREE;
        if (VOID_TYPE_P (type)) 
          cp_error_at ("instantiation of `%D' as type `%T'", r, type);
@@ -5949,7 +5956,7 @@ tsubst_decl (t, args, type)
       {
        r = copy_node (t);
        DECL_INITIAL (r)
-         = tsubst_copy (DECL_INITIAL (t), args, /*complain=*/1, in_decl);
+         = tsubst_copy (DECL_INITIAL (t), args, complain, in_decl);
        TREE_CHAIN (r) = NULL_TREE;
       }
       break;
@@ -5982,7 +5989,7 @@ tsubst_decl (t, args, type)
 
        if (TYPE_P (CP_DECL_CONTEXT (t)))
          ctx = tsubst_aggr_type (DECL_CONTEXT (t), args, 
-                                 /*complain=*/1,
+                                 complain,
                                  in_decl, /*entering_scope=*/1);
        else if (DECL_NAMESPACE_SCOPE_P (t))
          ctx = DECL_CONTEXT (t);
@@ -5998,7 +6005,7 @@ tsubst_decl (t, args, type)
          {
            tmpl = DECL_TI_TEMPLATE (t);
            gen_tmpl = most_general_template (tmpl);
-           argvec = tsubst (DECL_TI_ARGS (t), args, /*complain=*/1, in_decl);
+           argvec = tsubst (DECL_TI_ARGS (t), args, complain, in_decl);
            spec = retrieve_specialization (gen_tmpl, argvec);
          }
        else
@@ -6076,7 +6083,7 @@ static tree
 tsubst_arg_types (arg_types, args, complain, in_decl)
      tree arg_types;
      tree args;
-     int complain;
+     tsubst_flags_t complain;
      tree in_decl;
 {
   tree remaining_arg_types;
@@ -6095,7 +6102,7 @@ tsubst_arg_types (arg_types, args, complain, in_decl)
     return error_mark_node;
   if (VOID_TYPE_P (type))
     {
-      if (complain)
+      if (complain & tf_error)
         {
           error ("invalid parameter type `%T'", type);
           if (in_decl)
@@ -6137,7 +6144,7 @@ static tree
 tsubst_function_type (t, args, complain, in_decl)
      tree t;
      tree args;
-     int complain;
+     tsubst_flags_t complain;
      tree in_decl;
 {
   tree return_type;
@@ -6173,7 +6180,7 @@ tsubst_function_type (t, args, complain, in_decl)
             
             -- Attempting to create "pointer to member of T" when T
             is not a class type.  */
-         if (complain)
+         if (complain & tf_error)
            error ("creating pointer to member function of non-class type `%T'",
                      r);
          return error_mark_node;
@@ -6182,7 +6189,7 @@ tsubst_function_type (t, args, complain, in_decl)
       fntype = build_cplus_method_type (r, return_type, TREE_CHAIN
                                        (arg_types));
     }
-  fntype = build_qualified_type (fntype, TYPE_QUALS (t));
+  fntype = cp_build_qualified_type_real (fntype, TYPE_QUALS (t), complain);
   fntype = build_type_attribute_variant (fntype, TYPE_ATTRIBUTES (t));
   
   return fntype;  
@@ -6194,7 +6201,7 @@ static tree
 tsubst_call_declarator_parms (parms, args, complain, in_decl)
      tree parms;
      tree args;
-     int complain;
+     tsubst_flags_t complain;
      tree in_decl;
 {
   tree new_parms;
@@ -6228,15 +6235,15 @@ tsubst_call_declarator_parms (parms, args, complain, in_decl)
 /* Take the tree structure T and replace template parameters used
    therein with the argument vector ARGS.  IN_DECL is an associated
    decl for diagnostics.  If an error occurs, returns ERROR_MARK_NODE.
-   An appropriate error message is issued only if COMPLAIN is
-   non-zero.  Note that we must be relatively non-tolerant of
-   extensions here, in order to preserve conformance; if we allow
-   substitutions that should not be allowed, we may allow argument
-   deductions that should not succeed, and therefore report ambiguous
-   overload situations where there are none.  In theory, we could
-   allow the substitution, but indicate that it should have failed,
-   and allow our caller to make sure that the right thing happens, but
-   we don't try to do this yet.
+   Issue error and warning messages under control of COMPLAIN.  Note
+   that we must be relatively non-tolerant of extensions here, in
+   order to preserve conformance; if we allow substitutions that
+   should not be allowed, we may allow argument deductions that should
+   not succeed, and therefore report ambiguous overload situations
+   where there are none.  In theory, we could allow the substitution,
+   but indicate that it should have failed, and allow our caller to
+   make sure that the right thing happens, but we don't try to do this
+   yet.
 
    This function is used for dealing with types, decls and the like;
    for expressions, use tsubst_expr or tsubst_copy.  */
@@ -6244,7 +6251,7 @@ tsubst_call_declarator_parms (parms, args, complain, in_decl)
 tree
 tsubst (t, args, complain, in_decl)
      tree t, args;
-     int complain;
+     tsubst_flags_t complain;
      tree in_decl;
 {
   tree type, r;
@@ -6274,7 +6281,7 @@ tsubst (t, args, complain, in_decl)
     return error_mark_node;
 
   if (DECL_P (t))
-    return tsubst_decl (t, args, type);
+    return tsubst_decl (t, args, type, complain);
 
   switch (TREE_CODE (t))
     {
@@ -6350,7 +6357,7 @@ tsubst (t, args, complain, in_decl)
 
                 Attempting to create an array with a size that is
                 zero or negative.  */
-           if (complain)
+           if (complain & tf_error)
              error ("creating array with size zero (`%E')", max);
 
            return error_mark_node;
@@ -6424,9 +6431,8 @@ tsubst (t, args, complain, in_decl)
                                               DECL_CONTEXT (arg),
                                               /*entering_scope=*/0,
                                               complain);
-                   return cp_build_qualified_type_real (r, 
-                                                        TYPE_QUALS (t),
-                                                        complain);
+                   return cp_build_qualified_type_real
+                     (r, TYPE_QUALS (t), complain);
                  }
                else
                  /* TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX.  */
@@ -6453,8 +6459,8 @@ tsubst (t, args, complain, in_decl)
            if (cp_type_quals (t))
              {
                r = tsubst (TYPE_MAIN_VARIANT (t), args, complain, in_decl);
-               r = cp_build_qualified_type_real (r, cp_type_quals (t),
-                                                 complain);
+               r = cp_build_qualified_type_real
+                 (r, cp_type_quals (t), complain);
              }
            else
              {
@@ -6585,8 +6591,8 @@ tsubst (t, args, complain, in_decl)
            /* We keep track of the last time we issued this error
               message to avoid spewing a ton of messages during a
               single bad template instantiation.  */
-           if (complain && (last_line != lineno ||
-                            last_file != input_filename))
+           if (complain & tf_error
+               && (last_line != lineno || last_file != input_filename))
              {
                if (TREE_CODE (type) == VOID_TYPE)
                  error ("forming reference to void");
@@ -6628,9 +6634,8 @@ tsubst (t, args, complain, in_decl)
               
               -- Attempting to create "pointer to member of T" when T
                  is not a class type.  */
-           if (complain)
-             error ("creating pointer to member of non-class type `%T'", 
-                       r);
+           if (complain & tf_error)
+             error ("creating pointer to member of non-class type `%T'", r);
            return error_mark_node;
          }
        if (TREE_CODE (type) == REFERENCE_TYPE)
@@ -6713,7 +6718,7 @@ tsubst (t, args, complain, in_decl)
            || TREE_CODE (type) == FUNCTION_TYPE
            || TREE_CODE (type) == REFERENCE_TYPE)
          {
-           if (complain)
+           if (complain & tf_error)
              error ("creating array of `%T'", type);
            return error_mark_node;
          }
@@ -6725,10 +6730,8 @@ tsubst (t, args, complain, in_decl)
     case PLUS_EXPR:
     case MINUS_EXPR:
       {
-       tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain,
-                         in_decl);
-       tree e2 = tsubst (TREE_OPERAND (t, 1), args, complain,
-                         in_decl);
+       tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl);
+       tree e2 = tsubst (TREE_OPERAND (t, 1), args, complain, in_decl);
 
        if (e1 == error_mark_node || e2 == error_mark_node)
          return error_mark_node;
@@ -6739,8 +6742,7 @@ tsubst (t, args, complain, in_decl)
     case NEGATE_EXPR:
     case NOP_EXPR:
       {
-       tree e = tsubst (TREE_OPERAND (t, 0), args, complain,
-                         in_decl);
+       tree e = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl);
        if (e == error_mark_node)
          return error_mark_node;
 
@@ -6759,7 +6761,7 @@ tsubst (t, args, complain, in_decl)
 
        if (!IS_AGGR_TYPE (ctx))
          {
-           if (complain)
+           if (complain & tf_error)
              error ("`%T' is not a class, struct, or union type",
                        ctx);
            return error_mark_node;
@@ -6777,21 +6779,19 @@ tsubst (t, args, complain, in_decl)
            ctx = complete_type (ctx);
            if (!COMPLETE_TYPE_P (ctx))
              {
-               if (complain)
+               if (complain & tf_error)
                  incomplete_type_error (NULL_TREE, ctx);
                return error_mark_node;
              }
          }
 
-       f = make_typename_type (ctx, f, complain);
+       f = make_typename_type (ctx, f, complain & tf_error);
        if (f == error_mark_node)
          return f;
-       return cp_build_qualified_type_real (f, 
-                                            cp_type_quals (f) 
-                                            | cp_type_quals (t),
-                                            complain);
+       return cp_build_qualified_type_real
+         (f, cp_type_quals (f) | cp_type_quals (t), complain);
       }
-
+              
     case UNBOUND_CLASS_TEMPLATE:
       {
        tree ctx = tsubst_aggr_type (TYPE_CONTEXT (t), args, complain,
@@ -6806,8 +6806,7 @@ tsubst (t, args, complain, in_decl)
 
     case INDIRECT_REF:
       {
-       tree e = tsubst (TREE_OPERAND (t, 0), args, complain,
-                        in_decl);
+       tree e = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl);
        if (e == error_mark_node)
          return error_mark_node;
        return make_pointer_declarator (type, e);
@@ -6815,8 +6814,7 @@ tsubst (t, args, complain, in_decl)
 
     case ADDR_EXPR:
       {
-       tree e = tsubst (TREE_OPERAND (t, 0), args, complain,
-                        in_decl);
+       tree e = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl);
        if (e == error_mark_node)
          return error_mark_node;
        return make_reference_declarator (type, e);
@@ -6824,10 +6822,8 @@ tsubst (t, args, complain, in_decl)
 
     case ARRAY_REF:
       {
-       tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain,
-                         in_decl);
-       tree e2 = tsubst_expr (TREE_OPERAND (t, 1), args, complain,
-                              in_decl);
+       tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl);
+       tree e2 = tsubst_expr (TREE_OPERAND (t, 1), args, complain, in_decl);
        if (e1 == error_mark_node || e2 == error_mark_node)
          return error_mark_node;
 
@@ -6836,8 +6832,7 @@ tsubst (t, args, complain, in_decl)
 
     case CALL_EXPR:
       {
-       tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain,
-                         in_decl);
+       tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl);
        tree e2 = (tsubst_call_declarator_parms
                   (CALL_DECLARATOR_PARMS (t), args, complain, in_decl));
        tree e3 = tsubst (CALL_DECLARATOR_EXCEPTION_SPEC (t), args,
@@ -6852,8 +6847,7 @@ tsubst (t, args, complain, in_decl)
 
     case SCOPE_REF:
       {
-       tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain,
-                                 in_decl);
+       tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl);
        tree e2 = tsubst (TREE_OPERAND (t, 1), args, complain, in_decl);
        if (e1 == error_mark_node || e2 == error_mark_node)
          return error_mark_node;
@@ -6863,8 +6857,7 @@ tsubst (t, args, complain, in_decl)
 
     case TYPEOF_TYPE:
       {
-       tree e1 = tsubst_expr (TYPE_FIELDS (t), args, complain,
-                              in_decl);
+       tree e1 = tsubst_expr (TYPE_FIELDS (t), args, complain, in_decl);
        if (e1 == error_mark_node)
          return error_mark_node;
 
@@ -6885,7 +6878,7 @@ tsubst (t, args, complain, in_decl)
 tree
 tsubst_copy (t, args, complain, in_decl)
      tree t, args;
-     int complain;
+     tsubst_flags_t complain;
      tree in_decl;
 {
   enum tree_code code;
@@ -7104,8 +7097,7 @@ tsubst_copy (t, args, complain, in_decl)
       if (!processing_template_decl)
        {
          tree stmt_expr = begin_stmt_expr ();
-         tsubst_expr (STMT_EXPR_STMT (t), args,
-                      complain, in_decl);
+         tsubst_expr (STMT_EXPR_STMT (t), args, complain, in_decl);
          return finish_stmt_expr (stmt_expr);
        }
       
@@ -7230,8 +7222,8 @@ tsubst_copy (t, args, complain, in_decl)
 
     case VA_ARG_EXPR:
       return build_x_va_arg (tsubst_copy (TREE_OPERAND (t, 0), args, complain,
-                                       in_decl),
-                          tsubst (TREE_TYPE (t), args, complain, in_decl));
+                                         in_decl),
+                            tsubst (TREE_TYPE (t), args, complain, in_decl));
 
     default:
       return t;
@@ -7243,7 +7235,7 @@ tsubst_copy (t, args, complain, in_decl)
 tree
 tsubst_expr (t, args, complain, in_decl)
      tree t, args;
-     int complain;
+     tsubst_flags_t complain;
      tree in_decl;
 {
   tree stmt, tmp;
@@ -7263,7 +7255,7 @@ tsubst_expr (t, args, complain, in_decl)
       prep_stmt (t);
       finish_named_return_value
        (TREE_OPERAND (t, 0),
-        tsubst_expr (TREE_OPERAND (t, 1), args, /*complain=*/1, in_decl));
+        tsubst_expr (TREE_OPERAND (t, 1), args, complain, in_decl));
       break;
 
     case CTOR_INITIALIZER:
@@ -7357,8 +7349,8 @@ tsubst_expr (t, args, complain, in_decl)
        stmt = begin_for_stmt ();
        tsubst_expr (FOR_INIT_STMT (t), args, complain, in_decl);
        finish_for_init_stmt (stmt);
-       finish_for_cond (tsubst_expr (FOR_COND (t), args,
-                                     complain, in_decl),
+       finish_for_cond (tsubst_expr (FOR_COND (t),
+                                     args, complain, in_decl),
                         stmt);
        tmp = tsubst_expr (FOR_EXPR (t), args, complain, in_decl);
        finish_for_expr (tmp, stmt);
@@ -7385,8 +7377,8 @@ tsubst_expr (t, args, complain, in_decl)
        stmt = begin_do_stmt ();
        tsubst_expr (DO_BODY (t), args, complain, in_decl);
        finish_do_body (stmt);
-       finish_do_stmt (tsubst_expr (DO_COND (t), args,
-                                    complain, in_decl),
+       finish_do_stmt (tsubst_expr (DO_COND (t),
+                                    args, complain, in_decl),
                        stmt);
       }
       break;
@@ -7638,7 +7630,7 @@ instantiate_template (tmpl, targ_ptr)
 
   /* substitute template parameters */
   fndecl = tsubst (DECL_TEMPLATE_RESULT (gen_tmpl),
-                  targ_ptr, /*complain=*/1, gen_tmpl);
+                  targ_ptr, tf_error, gen_tmpl);
   /* The DECL_TI_TEMPLATE should always be the immediate parent
      template, not the most general template.  */
   DECL_TI_TEMPLATE (fndecl) = tmpl;
@@ -7735,12 +7727,12 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type,
 
       converted_args
        = (coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (fn), 
-                                 explicit_targs, NULL_TREE, /*complain=*/0
+                                 explicit_targs, NULL_TREE, tf_none
                                  /*require_all_arguments=*/0));
       if (converted_args == error_mark_node)
        return 1;
 
-      fntype = tsubst (fntype, converted_args, /*complain=*/0, NULL_TREE);
+      fntype = tsubst (fntype, converted_args, tf_none, NULL_TREE);
       if (fntype == error_mark_node)
        return 1;
 
@@ -7781,7 +7773,7 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type,
        the corresponding deduced argument values.  If the
        substitution results in an invalid type, as described above,
        type deduction fails.  */
-    if (tsubst (TREE_TYPE (fn), targs, /*complain=*/0, NULL_TREE)
+    if (tsubst (TREE_TYPE (fn), targs, tf_none, NULL_TREE)
        == error_mark_node)
       return 1;
 
@@ -8117,8 +8109,7 @@ resolve_overloaded_unification (tparms, targs, parm, arg, strict,
                                           expl_subargs);
          if (subargs)
            {
-             elem = tsubst (TREE_TYPE (fn), subargs, /*complain=*/0,
-                            NULL_TREE);
+             elem = tsubst (TREE_TYPE (fn), subargs, tf_none, NULL_TREE);
              if (TREE_CODE (elem) == METHOD_TYPE)
                elem = build_ptrmemfunc_type (build_pointer_type (elem));
              good += try_one_overload (tparms, targs, tempargs, parm, elem,
@@ -8256,7 +8247,7 @@ verify_class_unification (targs, parms, args)
   int i;
   int nparms = TREE_VEC_LENGTH (parms);
   tree new_parms = tsubst (parms, add_outermost_template_args (args, targs),
-                          /*complain=*/0, NULL_TREE);
+                          tf_none, NULL_TREE);
   if (new_parms == error_mark_node)
     return 1;
 
@@ -8680,11 +8671,8 @@ unify (tparms, targs, parm, arg, strict)
 
          /* Consider the case where ARG is `const volatile int' and
             PARM is `const T'.  Then, T should be `volatile int'.  */
-         arg = 
-           cp_build_qualified_type_real (arg,
-                                         cp_type_quals (arg) 
-                                         & ~cp_type_quals (parm),
-                                         /*complain=*/0);
+         arg = cp_build_qualified_type_real
+           (arg, cp_type_quals (arg) & ~cp_type_quals (parm), tf_none);
          if (arg == error_mark_node)
            return 1;
 
@@ -9154,13 +9142,11 @@ get_bindings_real (fn, decl, explicit_args, check_rettype, deduce, len)
       converted_args
        = (coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
                                  explicit_args, NULL_TREE,
-                                 /*complain=*/0, 
-                                 /*require_all_arguments=*/0));
+                                 tf_none, /*require_all_arguments=*/0));
       if (converted_args == error_mark_node)
        return NULL_TREE;
       
-      decl_type = tsubst (decl_type, converted_args, /*complain=*/0, 
-                         NULL_TREE); 
+      decl_type = tsubst (decl_type, converted_args, tf_none, NULL_TREE); 
       if (decl_type == error_mark_node)
        return NULL_TREE;
     }
@@ -9555,7 +9541,7 @@ mark_class_instantiated (t, extern_p)
 void
 do_type_instantiation (t, storage, complain)
      tree t, storage;
-     int complain;
+     tsubst_flags_t complain;
 {
   int extern_p = 0;
   int nomem_p = 0;
@@ -9579,7 +9565,7 @@ do_type_instantiation (t, storage, complain)
 
   if (!COMPLETE_TYPE_P (t))
     {
-      if (complain)
+      if (complain & tf_error)
        error ("explicit instantiation of `%#T' before definition of template",
                  t);
       return;
@@ -9611,7 +9597,7 @@ do_type_instantiation (t, storage, complain)
 
         No program shall both explicitly instantiate and explicitly
         specialize a template.  */
-      if (complain)
+      if (complain & tf_error)
        {
          error ("explicit instantiation of `%#T' after", t);
          cp_error_at ("explicit specialization here", t);
@@ -9630,7 +9616,7 @@ do_type_instantiation (t, storage, complain)
         are we already got marked as an explicit instantiation because of the
         repo file.  All these cases are OK.  */
       if (!CLASSTYPE_INTERFACE_ONLY (t) && !extern_p && !flag_use_repository
-         && complain)
+         && (complain & tf_error))
        pedwarn ("duplicate explicit instantiation of `%#T'", t);
       
       /* If we've already instantiated the template, just return now.  */
@@ -9750,14 +9736,14 @@ regenerate_decl_from_template (decl, tmpl)
     pushclass (DECL_CONTEXT (decl), 2);
 
   /* Do the substitution to get the new declaration.  */
-  new_decl = tsubst (code_pattern, args, /*complain=*/1, NULL_TREE);
+  new_decl = tsubst (code_pattern, args, tf_error, NULL_TREE);
 
   if (TREE_CODE (decl) == VAR_DECL)
     {
       /* Set up DECL_INITIAL, since tsubst doesn't.  */
       DECL_INITIAL (new_decl) = 
        tsubst_expr (DECL_INITIAL (code_pattern), args, 
-                    /*complain=*/1, DECL_TI_TEMPLATE (decl));
+                    tf_error, DECL_TI_TEMPLATE (decl));
       /* Pop the class context we pushed above.  */
       popclass ();
     }
@@ -10027,7 +10013,7 @@ instantiate_decl (d, defer_ok)
 
       /* Substitute into the body of the function.  */
       tsubst_expr (DECL_SAVED_TREE (code_pattern), args,
-                  /*complain=*/1, tmpl);
+                  tf_error | tf_warning, tmpl);
 
       /* We don't need the local specializations any more.  */
       htab_delete (local_specializations);
@@ -10159,9 +10145,9 @@ tsubst_initializer_list (t, argvec)
       tree init;
       tree val;
 
-      decl = tsubst_copy (TREE_PURPOSE (t), argvec, /*complain=*/1,
+      decl = tsubst_copy (TREE_PURPOSE (t), argvec, tf_error | tf_warning,
                          NULL_TREE);
-      init = tsubst_expr (TREE_VALUE (t), argvec, /*complain=*/1,
+      init = tsubst_expr (TREE_VALUE (t), argvec, tf_error | tf_warning,
                          NULL_TREE);
 
       if (!init)
@@ -10211,7 +10197,7 @@ tsubst_enum (tag, newtag, args)
       /* Note that in a template enum, the TREE_VALUE is the
         CONST_DECL, not the corresponding INTEGER_CST.  */
       value = tsubst_expr (DECL_INITIAL (TREE_VALUE (e)), 
-                          args, /*complain=*/1,
+                          args, tf_error | tf_warning,
                           NULL_TREE);
 
       /* Give this enumeration constant the correct access.  */
@@ -10280,16 +10266,16 @@ get_mostly_instantiated_function_type (decl, contextp, tparmsp)
 
       /* Now, do the (partial) substitution to figure out the
         appropriate function type.  */
-      fn_type = tsubst (fn_type, partial_args, /*complain=*/1, NULL_TREE);
+      fn_type = tsubst (fn_type, partial_args, tf_error, NULL_TREE);
       if (DECL_STATIC_FUNCTION_P (decl))
-       context = tsubst (context, partial_args, /*complain=*/1, NULL_TREE);
+       context = tsubst (context, partial_args, tf_error, NULL_TREE);
 
       /* Substitute into the template parameters to obtain the real
         innermost set of parameters.  This step is important if the
         innermost set of template parameters contains value
         parameters whose types depend on outer template parameters.  */
       TREE_VEC_LENGTH (partial_args)--;
-      tparms = tsubst_template_parms (tparms, partial_args, /*complain=*/1);
+      tparms = tsubst_template_parms (tparms, partial_args, tf_error);
     }
 
   if (contextp)
@@ -10322,13 +10308,13 @@ current_instantiation ()
 }
 
 /* [temp.param] Check that template non-type parm TYPE is of an allowable
-   type. Return zero for ok, non-zero for disallowed. If COMPLAIN is
-   non-zero, then complain. */
+   type. Return zero for ok, non-zero for disallowed. Issue error and
+   warning messages under control of COMPLAIN.  */
 
 static int
 invalid_nontype_parm_type_p (type, complain)
      tree type;
-     int complain;
+     tsubst_flags_t complain;
 {
   if (INTEGRAL_TYPE_P (type))
     return 0;
@@ -10343,7 +10329,7 @@ invalid_nontype_parm_type_p (type, complain)
   else if (TREE_CODE (type) == TYPENAME_TYPE)
     return 0;
            
-  if (complain)
+  if (complain & tf_error)
     error ("`%#T' is not a valid type for a template constant parameter",
               type);
   return 1;
index d353b06..2d99e02 100644 (file)
@@ -505,16 +505,15 @@ build_cplus_array_type (elt_type, index_type)
 \f
 /* Make a variant of TYPE, qualified with the TYPE_QUALS.  Handles
    arrays correctly.  In particular, if TYPE is an array of T's, and
-   TYPE_QUALS is non-empty, returns an array of qualified T's.  If
-   at attempt is made to qualify a type illegally, and COMPLAIN is
-   non-zero, an error is issued.  If COMPLAIN is zero, error_mark_node
-   is returned.  */
+   TYPE_QUALS is non-empty, returns an array of qualified T's.
+   Errors are emitted under control of COMPLAIN. If COMPLAIN is zero,
+   error_mark_node is returned for bad qualifiers.  */
 
 tree
 cp_build_qualified_type_real (type, type_quals, complain)
      tree type;
      int type_quals;
-     int complain;
+     tsubst_flags_t complain;
 {
   tree result;
 
@@ -532,7 +531,7 @@ cp_build_qualified_type_real (type, type_quals, complain)
          || TYPE_PTRMEM_P (type)
          || TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE))
     {
-      if (complain)
+      if (complain & tf_error)
        error ("`%T' cannot be `restrict'-qualified", type);
       else
        return error_mark_node;
@@ -543,7 +542,7 @@ cp_build_qualified_type_real (type, type_quals, complain)
   if (type_quals != TYPE_UNQUALIFIED
       && TREE_CODE (type) == FUNCTION_TYPE)
     {
-      if (complain)
+      if (complain & tf_error)
        error ("`%T' cannot be `const'-, `volatile'-, or `restrict'-qualified", type);
       else
        return error_mark_node;
index 4cc576b..4d0cf78 100644 (file)
@@ -3414,7 +3414,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
   /* DTRT if one side is an overloaded function, but complain about it.  */
   if (type_unknown_p (op0))
     {
-      tree t = instantiate_type (TREE_TYPE (op1), op0, itf_none);
+      tree t = instantiate_type (TREE_TYPE (op1), op0, tf_none);
       if (t != error_mark_node)
        {
          pedwarn ("assuming cast to type `%T' from overloaded function",
@@ -3424,7 +3424,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
     }
   if (type_unknown_p (op1))
     {
-      tree t = instantiate_type (TREE_TYPE (op0), op1, itf_none);
+      tree t = instantiate_type (TREE_TYPE (op0), op1, tf_none);
       if (t != error_mark_node)
        {
          pedwarn ("assuming cast to type `%T' from overloaded function",
@@ -6106,7 +6106,7 @@ build_ptrmemfunc (type, pfn, force)
     }
 
   if (type_unknown_p (pfn))
-    return instantiate_type (type, pfn, itf_complain);
+    return instantiate_type (type, pfn, tf_error | tf_warning);
 
   fn = TREE_OPERAND (pfn, 0);
   my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 0);
@@ -6334,7 +6334,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
             overloaded function.  Call instantiate_type to get error
             messages.  */
          if (rhstype == unknown_type_node)
-           instantiate_type (type, rhs, itf_complain);
+           instantiate_type (type, rhs, tf_error | tf_warning);
          else if (fndecl)
            error ("cannot convert `%T' to `%T' for argument `%P' to `%D'",
                      rhstype, type, parmnum, fndecl);