diff options
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r-- | gcc/cp/pt.c | 1382 |
1 files changed, 709 insertions, 673 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 4d650c5e23d..12baea14a33 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -88,20 +88,18 @@ static htab_t local_specializations; #define GTB_IGNORE_TYPE 2 /* We don't need to try to unify the current type with the desired type. */ -static void push_access_scope_real (tree, tree, tree); static void push_access_scope (tree); static void pop_access_scope (tree); static int resolve_overloaded_unification (tree, tree, tree, tree, unification_kind_t, int); static int try_one_overload (tree, tree, tree, tree, tree, - unification_kind_t, int); + unification_kind_t, int, bool); static int unify (tree, tree, tree, tree, int); static void add_pending_template (tree); static void reopen_tinst_level (tree); static tree classtype_mangled_name (tree); static char* mangle_class_name_for_template (const char *, tree, tree); static tree tsubst_initializer_list (tree, tree); -static int list_eq (tree, tree); static tree get_class_bindings (tree, tree, tree); static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t, int); static void tsubst_enum (tree, tree, tree); @@ -112,8 +110,6 @@ static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*); static int type_unification_real (tree, tree, tree, tree, int, unification_kind_t, int, int); static void note_template_header (int); -static tree maybe_fold_nontype_arg (tree); -static void maybe_fold_nontype_args (tree); static tree convert_nontype_argument (tree, tree); static tree convert_template_argument (tree, tree, tree, tsubst_flags_t, int, tree); @@ -126,7 +122,6 @@ static tree retrieve_specialization (tree, tree); static tree retrieve_local_specialization (tree); static tree register_specialization (tree, tree, tree); static void register_local_specialization (tree, tree); -static int unregister_specialization (tree, tree); static tree reduce_template_parm_level (tree, tree, int); static tree build_template_decl (tree, tree); static int mark_template_parm (tree, void *); @@ -134,10 +129,12 @@ static int template_parm_this_level_p (tree, void *); static tree tsubst_friend_function (tree, tree); static tree tsubst_friend_class (tree, tree); static int can_complete_type_without_circularity (tree); +static tree get_bindings (tree, tree, tree); static tree get_bindings_real (tree, tree, tree, int, int, int); static int template_decl_level (tree); static int check_cv_quals_for_unify (int, tree, tree); -static tree tsubst_template_arg_vector (tree, tree, tsubst_flags_t); +static tree tsubst_template_arg (tree, tree, tsubst_flags_t, tree); +static tree tsubst_template_args (tree, tree, tsubst_flags_t, tree); static tree tsubst_template_parms (tree, tree, tsubst_flags_t); static void regenerate_decl_from_template (tree, tree); static tree most_specialized (tree, tree, tree); @@ -173,49 +170,22 @@ static tree tsubst_copy (tree, tree, tsubst_flags_t, tree); /* Make the current scope suitable for access checking when we are processing T. T can be FUNCTION_DECL for instantiated function - template, TEMPLATE_DECL for uninstantiated one, or VAR_DECL for - static member variable (need by instantiate_decl). ARGS is the - template argument for TEMPLATE_DECL. If CONTEXT is not NULL_TREE, - this is used instead of the context of T. */ + template, or VAR_DECL for static member variable (need by + instantiate_decl). */ static void -push_access_scope_real (tree t, tree args, tree context) +push_access_scope (tree t) { - if (TREE_CODE (t) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (t)) - { - /* When we are processing specialization `foo<Outer>' for code like - - template <class U> typename U::Inner foo (); - class Outer { - struct Inner {}; - friend Outer::Inner foo<Outer> (); - }; - - `T' is a TEMPLATE_DECL, but `Outer' is only a friend of one of - its specialization. We can get the FUNCTION_DECL with the right - information because this specialization has already been - registered by the friend declaration above. */ - - if (DECL_FUNCTION_TEMPLATE_P (t) && args) - { - tree full_args = tsubst_template_arg_vector - (DECL_TI_ARGS (DECL_TEMPLATE_RESULT (t)), args, tf_none); - tree spec = NULL_TREE; - if (full_args != error_mark_node) - spec = retrieve_specialization (t, full_args); - if (spec) - t = spec; - } - } + my_friendly_assert (TREE_CODE (t) == FUNCTION_DECL + || TREE_CODE (t) == VAR_DECL, + 0); - if (!context) - context = DECL_CONTEXT (t); - if (context && TYPE_P (context)) - push_nested_class (context); + if (DECL_CLASS_SCOPE_P (t)) + push_nested_class (DECL_CONTEXT (t)); else push_to_top_level (); - if (TREE_CODE (t) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (t)) + if (TREE_CODE (t) == FUNCTION_DECL) { saved_access_scope = tree_cons (NULL_TREE, current_function_decl, saved_access_scope); @@ -223,21 +193,13 @@ push_access_scope_real (tree t, tree args, tree context) } } -/* Like push_access_scope_real, but always uses DECL_CONTEXT. */ - -static void -push_access_scope (tree t) -{ - push_access_scope_real (t, NULL_TREE, NULL_TREE); -} - /* Restore the scope set up by push_access_scope. T is the node we are processing. */ static void pop_access_scope (tree t) { - if (TREE_CODE (t) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (t)) + if (TREE_CODE (t) == FUNCTION_DECL) { current_function_decl = TREE_VALUE (saved_access_scope); saved_access_scope = TREE_CHAIN (saved_access_scope); @@ -876,9 +838,8 @@ retrieve_specialization (tree tmpl, tree args) static tree retrieve_local_specialization (tree tmpl) { - tree spec = - (tree) htab_find_with_hash (local_specializations, tmpl, - htab_hash_pointer (tmpl)); + tree spec = htab_find_with_hash (local_specializations, tmpl, + htab_hash_pointer (tmpl)); return spec ? TREE_PURPOSE (spec) : NULL_TREE; } @@ -1023,11 +984,11 @@ register_specialization (tree spec, tree tmpl, tree args) } /* Unregister the specialization SPEC as a specialization of TMPL. - Returns nonzero if the SPEC was listed as a specialization of - TMPL. */ + Replace it with NEW_SPEC, if NEW_SPEC is non-NULL. Returns true + if the SPEC was listed as a specialization of TMPL. */ -static int -unregister_specialization (tree spec, tree tmpl) +bool +reregister_specialization (tree spec, tree tmpl, tree new_spec) { tree* s; @@ -1036,7 +997,10 @@ unregister_specialization (tree spec, tree tmpl) s = &TREE_CHAIN (*s)) if (TREE_VALUE (*s) == spec) { - *s = TREE_CHAIN (*s); + if (!new_spec) + *s = TREE_CHAIN (*s); + else + TREE_VALUE (*s) = new_spec; return 1; } @@ -1418,9 +1382,9 @@ copy_default_args_to_explicit_spec (tree decl) TREE_VALUE (in_charge), new_spec_types); - new_type = build_cplus_method_type (object_type, - TREE_TYPE (old_type), - new_spec_types); + new_type = build_method_type_directly (object_type, + TREE_TYPE (old_type), + new_spec_types); } else new_type = build_function_type (TREE_TYPE (old_type), @@ -1673,15 +1637,6 @@ check_explicit_specialization (tree declarator, return decl; } - else if (TREE_CODE (TREE_OPERAND (declarator, 0)) == LOOKUP_EXPR) - { - /* A friend declaration. We can't do much, because we don't - know what this resolves to, yet. */ - my_friendly_assert (is_friend != 0, 0); - my_friendly_assert (!explicit_instantiation, 0); - SET_DECL_IMPLICIT_INSTANTIATION (decl); - return decl; - } else if (ctype != NULL_TREE && (TREE_CODE (TREE_OPERAND (declarator, 0)) == IDENTIFIER_NODE)) @@ -2451,11 +2406,11 @@ process_partial_specialization (tree decl) { /* We haven't yet initialized TPD2. Do so now. */ tpd2.arg_uses_template_parms - = (int*) alloca (sizeof (int) * nargs); + = alloca (sizeof (int) * nargs); /* The number of parameters here is the number in the main template, which, as checked in the assertion above, is NARGS. */ - tpd2.parms = (int*) alloca (sizeof (int) * nargs); + tpd2.parms = alloca (sizeof (int) * nargs); tpd2.level = TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (maintmpl)); } @@ -2719,6 +2674,15 @@ push_template_decl_real (tree decl, int is_friend) else if (TREE_CODE (decl) == TYPE_DECL && ANON_AGGRNAME_P (DECL_NAME (decl))) error ("template class without a name"); + else if (TREE_CODE (decl) == FUNCTION_DECL + && DECL_DESTRUCTOR_P (decl)) + { + /* [temp.mem] + + A destructor shall not be a member template. */ + error ("destructor `%D' declared as member template", decl); + return error_mark_node; + } else if ((DECL_IMPLICIT_TYPEDEF_P (decl) && CLASS_TYPE_P (TREE_TYPE (decl))) || (TREE_CODE (decl) == VAR_DECL && ctx && CLASS_TYPE_P (ctx)) @@ -2982,8 +2946,7 @@ redeclare_class_template (tree type, tree parms) A template-parameter may not be given default arguments by two different declarations in the same scope. */ error ("redefinition of default argument for `%#D'", parm); - error ("%H original definition appeared here", - &DECL_SOURCE_LOCATION (tmpl_parm)); + error ("%J original definition appeared here", tmpl_parm); return; } @@ -3047,14 +3010,12 @@ convert_nontype_argument (tree type, tree expr) Check this first since if expr_type is the unknown_type_node we would otherwise complain below. */ ; - else if (TYPE_PTRMEM_P (expr_type) - || TYPE_PTRMEMFUNC_P (expr_type)) + else if (TYPE_PTR_TO_MEMBER_P (expr_type)) { if (TREE_CODE (expr) != PTRMEM_CST) goto bad_argument; } else if (TYPE_PTR_P (expr_type) - || TYPE_PTRMEM_P (expr_type) || TREE_CODE (expr_type) == ARRAY_TYPE || TREE_CODE (type) == REFERENCE_TYPE /* If expr is the address of an overloaded function, we @@ -3082,8 +3043,7 @@ convert_nontype_argument (tree type, tree expr) else error ("it must be the address of an object with external linkage"); } - else if (TYPE_PTRMEM_P (expr_type) - || TYPE_PTRMEMFUNC_P (expr_type)) + else if (TYPE_PTR_TO_MEMBER_P (expr_type)) error ("it must be a pointer-to-member of the form `&X::Y'"); return NULL_TREE; @@ -3100,6 +3060,9 @@ convert_nontype_argument (tree type, tree expr) return NULL_TREE; } + if (TREE_CODE (referent) == SCOPE_REF) + referent = TREE_OPERAND (referent, 1); + if (is_overloaded_fn (referent)) /* We'll check that it has external linkage later. */ ; @@ -3111,9 +3074,7 @@ convert_nontype_argument (tree type, tree expr) return error_mark_node; } } - else if (INTEGRAL_TYPE_P (expr_type) - || TYPE_PTRMEM_P (expr_type) - || TYPE_PTRMEMFUNC_P (expr_type)) + else if (INTEGRAL_TYPE_P (expr_type) || TYPE_PTR_TO_MEMBER_P (expr_type)) { if (! TREE_CONSTANT (expr)) { @@ -3125,7 +3086,14 @@ convert_nontype_argument (tree type, tree expr) } else { - error ("object `%E' cannot be used as template argument", expr); + if (TYPE_P (expr)) + error ("type '%T' cannot be used as a value for a non-type " + "template-parameter", expr); + else if (DECL_P (expr)) + error ("invalid use of '%D' as a non-type template-argument", expr); + else + error ("invalid use of '%E' as a non-type template-argument", expr); + return NULL_TREE; } @@ -3151,31 +3119,32 @@ convert_nontype_argument (tree type, tree expr) goto non_constant; return expr; - + + case OFFSET_TYPE: + { + tree e; + + /* For a non-type template-parameter of type pointer to data + member, qualification conversions (_conv.qual_) are + applied. */ + e = perform_qualification_conversions (type, expr); + if (TREE_CODE (e) == NOP_EXPR) + /* The call to perform_qualification_conversions will + insert a NOP_EXPR over EXPR to do express conversion, + if necessary. But, that will confuse us if we use + this (converted) template parameter to instantiate + another template; then the thing will not look like a + valid template argument. So, just make a new + constant, of the appropriate type. */ + e = make_ptrmem_cst (type, PTRMEM_CST_MEMBER (expr)); + return e; + } + case POINTER_TYPE: { tree type_pointed_to = TREE_TYPE (type); - if (TYPE_PTRMEM_P (type)) - { - tree e; - - /* For a non-type template-parameter of type pointer to data - member, qualification conversions (_conv.qual_) are - applied. */ - e = perform_qualification_conversions (type, expr); - if (TREE_CODE (e) == NOP_EXPR) - /* The call to perform_qualification_conversions will - insert a NOP_EXPR over EXPR to do express conversion, - if necessary. But, that will confuse us if we use - this (converted) template parameter to instantiate - another template; then the thing will not look like a - valid template argument. So, just make a new - constant, of the appropriate type. */ - e = make_ptrmem_cst (type, PTRMEM_CST_MEMBER (expr)); - return e; - } - else if (TREE_CODE (type_pointed_to) == FUNCTION_TYPE) + if (TREE_CODE (type_pointed_to) == FUNCTION_TYPE) { /* For a non-type template-parameter of type pointer to function, only the function-to-pointer conversion @@ -3239,9 +3208,12 @@ convert_nontype_argument (tree type, tree expr) tree type_referred_to = TREE_TYPE (type); /* If this expression already has reference type, get the - underling object. */ + underlying object. */ if (TREE_CODE (expr_type) == REFERENCE_TYPE) { + if (TREE_CODE (expr) == NOP_EXPR + && TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR) + STRIP_NOPS (expr); my_friendly_assert (TREE_CODE (expr) == ADDR_EXPR, 20000604); expr = TREE_OPERAND (expr, 0); expr_type = TREE_TYPE (expr); @@ -3295,7 +3267,7 @@ convert_nontype_argument (tree type, tree expr) } cxx_mark_addressable (expr); - return build1 (ADDR_EXPR, type, expr); + return build_nop (type, build_address (expr)); } break; @@ -3409,9 +3381,8 @@ coerce_template_template_parms (tree parm_parms, tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm); tree argparm = DECL_INNERMOST_TEMPLATE_PARMS (arg); - if (!coerce_template_template_parms (parmparm, argparm, - complain, in_decl, - outer_args)) + if (!coerce_template_template_parms + (parmparm, argparm, complain, in_decl, outer_args)) return 0; } break; @@ -3420,9 +3391,9 @@ coerce_template_template_parms (tree parm_parms, /* The tsubst call is used to handle cases such as template <class T, template <T> class TT> class D; i.e. the parameter list of TT depends on earlier parameters. */ - if (!same_type_p (tsubst (TREE_TYPE (parm), outer_args, - complain, in_decl), - TREE_TYPE (arg))) + if (!same_type_p + (tsubst (TREE_TYPE (parm), outer_args, complain, in_decl), + TREE_TYPE (arg))) return 0; break; @@ -3455,8 +3426,7 @@ convert_template_argument (tree parm, inner_args = INNERMOST_TEMPLATE_ARGS (args); if (TREE_CODE (arg) == TREE_LIST - && TREE_TYPE (arg) != NULL_TREE - && TREE_CODE (TREE_TYPE (arg)) == OFFSET_TYPE) + && TREE_CODE (TREE_VALUE (arg)) == OFFSET_REF) { /* The template argument was the name of some member function. That's usually @@ -3471,33 +3441,15 @@ convert_template_argument (tree parm, requires_type = (TREE_CODE (parm) == TYPE_DECL || requires_tmpl_type); - if (TREE_CODE (arg) != RECORD_TYPE) - is_tmpl_type = ((TREE_CODE (arg) == TEMPLATE_DECL - && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL) - || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM - || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE); - else if (CLASSTYPE_TEMPLATE_INFO (arg) && !CLASSTYPE_USE_TEMPLATE (arg) - && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (arg))) - { - if (is_base_of_enclosing_class (arg, current_class_type)) - /* This is a template name used within the scope of the - template. It could be the template, or it could be the - instantiation. Choose whichever makes sense. */ - is_tmpl_type = requires_tmpl_type; - else - is_tmpl_type = 1; - } - else - /* It is a non-template class, or a specialization of a template - class, or a non-template member of a template class. */ - is_tmpl_type = 0; + is_tmpl_type = ((TREE_CODE (arg) == TEMPLATE_DECL + && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL) + || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM + || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE); if (is_tmpl_type && (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE)) arg = TYPE_STUB_DECL (arg); - else if (is_tmpl_type && TREE_CODE (arg) == RECORD_TYPE) - arg = CLASSTYPE_TI_TEMPLATE (arg); is_type = TYPE_P (arg) || is_tmpl_type; @@ -3641,7 +3593,7 @@ coerce_template_parms (tree parms, tree new_inner_args; inner_args = INNERMOST_TEMPLATE_ARGS (args); - nargs = NUM_TMPL_ARGS (inner_args); + nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0; nparms = TREE_VEC_LENGTH (parms); if (nargs > nparms @@ -3672,39 +3624,18 @@ coerce_template_parms (tree parms, parm = TREE_VEC_ELT (parms, i); /* Calculate the Ith argument. */ - if (inner_args && TREE_CODE (inner_args) == TREE_LIST) - { - arg = TREE_VALUE (inner_args); - inner_args = TREE_CHAIN (inner_args); - } - else if (i < nargs) + if (i < nargs) arg = TREE_VEC_ELT (inner_args, i); - /* If no template argument was supplied, look for a default - value. */ - else if (TREE_PURPOSE (parm) == NULL_TREE) - { - /* There was no default value. */ - my_friendly_assert (!require_all_arguments, 0); - break; - } - else if (TREE_CODE (TREE_VALUE (parm)) == TYPE_DECL) - arg = tsubst (TREE_PURPOSE (parm), new_args, complain, in_decl); + else if (require_all_arguments) + /* There must be a default arg in this case. */ + arg = tsubst_template_arg (TREE_PURPOSE (parm), new_args, + complain, in_decl); else - arg = tsubst_expr (TREE_PURPOSE (parm), new_args, complain, - in_decl); - - /* Now, convert the Ith argument, as necessary. */ - if (arg == NULL_TREE) - /* We're out of arguments. */ - { - my_friendly_assert (!require_all_arguments, 0); - break; - } - else if (arg == error_mark_node) - { - error ("template argument %d is invalid", i + 1); - arg = error_mark_node; - } + break; + + my_friendly_assert (arg, 20030727); + if (arg == error_mark_node) + error ("template argument %d is invalid", i + 1); else arg = convert_template_argument (TREE_VALUE (parm), arg, new_args, complain, i, @@ -3826,13 +3757,6 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist) else my_friendly_assert (TREE_CODE (parm) == PARM_DECL, 269); - if (TREE_CODE (arg) == TREE_LIST) - { - /* New list cell was built because old chain link was in - use. */ - my_friendly_assert (TREE_PURPOSE (arg) == NULL_TREE, 270); - arg = TREE_VALUE (arg); - } /* No need to check arglist against parmlist here; we did that in coerce_template_parms, called from lookup_template_class. */ cat (expr_as_string (arg, TFF_PLAIN_IDENTIFIER)); @@ -3928,7 +3852,9 @@ lookup_template_function (tree fns, tree arglist) if (fns == error_mark_node || arglist == error_mark_node) return error_mark_node; - if (fns == NULL_TREE) + my_friendly_assert (!arglist || TREE_CODE (arglist) == TREE_VEC, 20030726); + if (fns == NULL_TREE + || TREE_CODE (fns) == FUNCTION_DECL) { error ("non-template used as template"); return error_mark_node; @@ -3937,8 +3863,7 @@ lookup_template_function (tree fns, tree arglist) my_friendly_assert (TREE_CODE (fns) == TEMPLATE_DECL || TREE_CODE (fns) == OVERLOAD || BASELINK_P (fns) - || TREE_CODE (fns) == IDENTIFIER_NODE - || TREE_CODE (fns) == LOOKUP_EXPR, + || TREE_CODE (fns) == IDENTIFIER_NODE, 20020730); if (BASELINK_P (fns)) @@ -3979,9 +3904,6 @@ maybe_get_template_decl_from_type_decl (tree decl) parameters, find the desired type. D1 is the PTYPENAME terminal, and ARGLIST is the list of arguments. - (Actually ARGLIST may be either a TREE_LIST or a TREE_VEC. It will - be a TREE_LIST if called directly from the parser, and a TREE_VEC - otherwise.) IN_DECL, if non-NULL, is the template declaration we are trying to instantiate. @@ -4005,8 +3927,9 @@ lookup_template_class (tree d1, { tree template = NULL_TREE, parmlist; tree t; - + timevar_push (TV_NAME_LOOKUP); + if (TREE_CODE (d1) == IDENTIFIER_NODE) { if (IDENTIFIER_VALUE (d1) @@ -4066,11 +3989,10 @@ lookup_template_class (tree d1, } if (TREE_CODE (template) != TEMPLATE_DECL - /* If we're called from the parser, make sure it's a user visible - template. */ - || ((!arglist || TREE_CODE (arglist) == TREE_LIST) - && !DECL_TEMPLATE_PARM_P (template) - && !PRIMARY_TEMPLATE_P (template))) + /* Make sure it's a user visible template, if it was named by + the user. */ + || ((complain & tf_user) && !DECL_TEMPLATE_PARM_P (template) + && !PRIMARY_TEMPLATE_P (template))) { if (complain & tf_error) { @@ -4081,6 +4003,8 @@ lookup_template_class (tree d1, POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); } + complain &= ~tf_user; + if (DECL_TEMPLATE_TEMPLATE_PARM_P (template)) { /* Create a new TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM node to store @@ -4314,7 +4238,6 @@ lookup_template_class (tree d1, t = make_aggr_type (TREE_CODE (template_type)); CLASSTYPE_DECLARED_CLASS (t) = CLASSTYPE_DECLARED_CLASS (template_type); - CLASSTYPE_GOT_SEMICOLON (t) = 1; SET_CLASSTYPE_IMPLICIT_INSTANTIATION (t); TYPE_FOR_JAVA (t) = TYPE_FOR_JAVA (template_type); @@ -4611,7 +4534,6 @@ for_each_template_parm_r (tree* tp, int* walk_subtrees, void* d) case ARROW_EXPR: case DOTSTAR_EXPR: case TYPEID_EXPR: - case LOOKUP_EXPR: case PSEUDO_DTOR_EXPR: if (!fn) return error_mark_node; @@ -4944,8 +4866,9 @@ tsubst_friend_function (tree decl, tree args) DECL_TEMPLATE_INFO (old_decl) = new_friend_template_info; if (TREE_CODE (old_decl) != TEMPLATE_DECL) - /* duplicate_decls will take care of this case. */ - ; + reregister_specialization (new_friend, + most_general_template (old_decl), + old_decl); else { tree t; @@ -5077,6 +5000,8 @@ tsubst_friend_class (tree friend_tmpl, tree args) DECL_USE_TEMPLATE (tmpl) = 0; DECL_TEMPLATE_INFO (tmpl) = NULL_TREE; CLASSTYPE_USE_TEMPLATE (TREE_TYPE (tmpl)) = 0; + CLASSTYPE_TI_ARGS (TREE_TYPE (tmpl)) + = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (TREE_TYPE (tmpl))); /* Inject this template into the global scope. */ friend_type = TREE_TYPE (pushdecl_top_level (tmpl)); @@ -5105,7 +5030,8 @@ can_complete_type_without_circularity (tree type) return 1; else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type)) return can_complete_type_without_circularity (TREE_TYPE (type)); - else if (CLASS_TYPE_P (type) && TYPE_BEING_DEFINED (TYPE_MAIN_VARIANT (type))) + else if (CLASS_TYPE_P (type) + && TYPE_BEING_DEFINED (TYPE_MAIN_VARIANT (type))) return 0; else return 1; @@ -5144,8 +5070,7 @@ instantiate_class_template (tree type) for (t = DECL_TEMPLATE_SPECIALIZATIONS (template); t; t = TREE_CHAIN (t)) { - if (get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t), - args)) + if (get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t), args)) { cp_error_at ("%s %+#T", str, TREE_TYPE (t)); str = " "; @@ -5226,11 +5151,12 @@ instantiate_class_template (tree type) SET_CLASSTYPE_INTERFACE_UNKNOWN (type); } + /* Set the input location to the template definition. This is needed + if tsubsting causes an error. */ + input_location = DECL_SOURCE_LOCATION (TYPE_NAME (pattern)); + TYPE_HAS_CONSTRUCTOR (type) = TYPE_HAS_CONSTRUCTOR (pattern); TYPE_HAS_DESTRUCTOR (type) = TYPE_HAS_DESTRUCTOR (pattern); - TYPE_OVERLOADS_CALL_EXPR (type) = TYPE_OVERLOADS_CALL_EXPR (pattern); - TYPE_OVERLOADS_ARRAY_REF (type) = TYPE_OVERLOADS_ARRAY_REF (pattern); - TYPE_OVERLOADS_ARROW (type) = TYPE_OVERLOADS_ARROW (pattern); TYPE_HAS_NEW_OPERATOR (type) = TYPE_HAS_NEW_OPERATOR (pattern); TYPE_HAS_ARRAY_NEW_OPERATOR (type) = TYPE_HAS_ARRAY_NEW_OPERATOR (pattern); TYPE_GETS_DELETE (type) = TYPE_GETS_DELETE (pattern); @@ -5261,8 +5187,14 @@ instantiate_class_template (tree type) tree base_list = NULL_TREE; tree pbases = BINFO_BASETYPES (pbinfo); tree paccesses = BINFO_BASEACCESSES (pbinfo); + tree context = TYPE_CONTEXT (type); int i; + /* We must enter the scope containing the type, as that is where + the accessibility of types named in dependent bases are + looked up from. */ + push_scope (context ? context : global_namespace); + /* Substitute into each of the bases to determine the actual basetypes. */ for (i = 0; i < TREE_VEC_LENGTH (pbases); ++i) @@ -5289,6 +5221,8 @@ instantiate_class_template (tree type) /* Now call xref_basetypes to set up all the base-class information. */ xref_basetypes (type, base_list); + + pop_scope (context ? context : global_namespace); } /* Now that our base classes are set up, enter the scope of the @@ -5296,10 +5230,11 @@ instantiate_class_template (tree type) correctly. This is precisely analogous to what we do in begin_class_definition when defining an ordinary non-template class. */ - pushclass (type, true); + pushclass (type); /* Now members are processed in the order of declaration. */ - for (member = CLASSTYPE_DECL_LIST (pattern); member; member = TREE_CHAIN (member)) + for (member = CLASSTYPE_DECL_LIST (pattern); + member; member = TREE_CHAIN (member)) { tree t = TREE_VALUE (member); @@ -5320,12 +5255,14 @@ instantiate_class_template (tree type) if (TYPE_LANG_SPECIFIC (tag) && CLASSTYPE_IS_TEMPLATE (tag)) /* Unfortunately, lookup_template_class sets CLASSTYPE_IMPLICIT_INSTANTIATION for a partial - instantiation (i.e., for the type of a member template - class nested within a template class.) This behavior is - required for maybe_process_partial_specialization to work - correctly, but is not accurate in this case; the TAG is not - an instantiation of anything. (The corresponding - TEMPLATE_DECL is an instantiation, but the TYPE is not.) */ + instantiation (i.e., for the type of a member + template class nested within a template class.) + This behavior is required for + maybe_process_partial_specialization to work + correctly, but is not accurate in this case; + the TAG is not an instantiation of anything. + (The corresponding TEMPLATE_DECL is an + instantiation, but the TYPE is not.) */ CLASSTYPE_USE_TEMPLATE (newtag) = 0; /* Now, we call pushtag to put this NEWTAG into the scope of @@ -5342,8 +5279,13 @@ instantiate_class_template (tree type) || DECL_FUNCTION_TEMPLATE_P (t)) { /* Build new TYPE_METHODS. */ - - tree r = tsubst (t, args, tf_error, NULL_TREE); + tree r; + + if (TREE_CODE (t) == TEMPLATE_DECL) + processing_template_decl++; + r = tsubst (t, args, tf_error, NULL_TREE); + if (TREE_CODE (t) == TEMPLATE_DECL) + processing_template_decl--; set_current_access_from_decl (r); grok_special_member_properties (r); finish_member_declaration (r); @@ -5362,7 +5304,11 @@ instantiate_class_template (tree type) restore these. */ input_location = DECL_SOURCE_LOCATION (t); + if (TREE_CODE (t) == TEMPLATE_DECL) + processing_template_decl++; r = tsubst (t, args, tf_error | tf_warning, NULL_TREE); + if (TREE_CODE (t) == TEMPLATE_DECL) + processing_template_decl--; if (TREE_CODE (r) == VAR_DECL) { tree init; @@ -5373,9 +5319,8 @@ instantiate_class_template (tree type) else init = NULL_TREE; - finish_static_data_member_decl (r, init, - /*asmspec_tree=*/NULL_TREE, - /*flags=*/0); + finish_static_data_member_decl + (r, init, /*asmspec_tree=*/NULL_TREE, /*flags=*/0); if (DECL_INITIALIZED_IN_CLASS_P (r)) check_static_variable_definition (r, TREE_TYPE (r)); @@ -5448,14 +5393,16 @@ instantiate_class_template (tree type) ++processing_template_decl; if (new_friend_type != error_mark_node) - make_friend_class (type, new_friend_type); + make_friend_class (type, new_friend_type, + /*complain=*/false); if (TREE_CODE (friend_type) == TEMPLATE_DECL) --processing_template_decl; } else /* Build new DECL_FRIENDLIST. */ - add_friend (type, tsubst_friend_function (t, args)); + add_friend (type, tsubst_friend_function (t, args), + /*complain=*/false); } } @@ -5468,7 +5415,6 @@ instantiate_class_template (tree type) unreverse_member_declarations (type); finish_struct_1 (type); - CLASSTYPE_GOT_SEMICOLON (type) = 1; /* Clear this now so repo_template_used is happy. */ TYPE_BEING_DEFINED (type) = 0; @@ -5497,108 +5443,78 @@ instantiate_class_template (tree type) return type; } -static int -list_eq (tree t1, tree t2) -{ - if (t1 == NULL_TREE) - return t2 == NULL_TREE; - if (t2 == NULL_TREE) - return 0; - /* Don't care if one declares its arg const and the other doesn't -- the - main variant of the arg type is all that matters. */ - if (TYPE_MAIN_VARIANT (TREE_VALUE (t1)) - != TYPE_MAIN_VARIANT (TREE_VALUE (t2))) - return 0; - return list_eq (TREE_CHAIN (t1), TREE_CHAIN (t2)); -} - -/* If arg is a non-type template parameter that does not depend on template - arguments, fold it like we weren't in the body of a template. */ - static tree -maybe_fold_nontype_arg (tree arg) +tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl) { - if (arg && !TYPE_P (arg) && !uses_template_parms (arg)) + tree r; + + if (!t) + r = t; + else if (TYPE_P (t)) + r = tsubst (t, args, complain, in_decl); + else { - /* Sometimes, one of the args was an expression involving a - template constant parameter, like N - 1. Now that we've - tsubst'd, we might have something like 2 - 1. This will - confuse lookup_template_class, so we do constant folding - here. We have to unset processing_template_decl, to fool - tsubst_copy_and_build() into building an actual tree. */ + r = tsubst_expr (t, args, complain, in_decl); - /* If the TREE_TYPE of ARG is not NULL_TREE, ARG is already - as simple as it's going to get, and trying to reprocess - the trees will break. */ - if (!TREE_TYPE (arg)) + if (!uses_template_parms (r)) { - int saved_processing_template_decl = processing_template_decl; - processing_template_decl = 0; - arg = tsubst_copy_and_build (arg, - /*args=*/NULL_TREE, - tf_error, - /*in_decl=*/NULL_TREE); - processing_template_decl = saved_processing_template_decl; - } + /* Sometimes, one of the args was an expression involving a + template constant parameter, like N - 1. Now that we've + tsubst'd, we might have something like 2 - 1. This will + confuse lookup_template_class, so we do constant folding + here. We have to unset processing_template_decl, to fool + tsubst_copy_and_build() into building an actual tree. */ - arg = fold (arg); - } - return arg; -} - -/* Apply maybe_fold_nontype_arg on a list or vector of args. */ - -static void -maybe_fold_nontype_args (tree targs) -{ - if (!targs) - /*OK*/; - else if (TREE_CODE (targs) == TREE_LIST) - { - tree chain; - for (chain = targs; chain; chain = TREE_CHAIN (chain)) - TREE_VALUE (chain) = maybe_fold_nontype_arg (TREE_VALUE (chain)); - } - else - { - int i; - for (i = 0; i < TREE_VEC_LENGTH (targs); ++i) - TREE_VEC_ELT (targs, i) - = maybe_fold_nontype_arg (TREE_VEC_ELT (targs, i)); + /* If the TREE_TYPE of ARG is not NULL_TREE, ARG is already + as simple as it's going to get, and trying to reprocess + the trees will break. Once tsubst_expr et al DTRT for + non-dependent exprs, this code can go away, as the type + will always be set. */ + if (!TREE_TYPE (r)) + { + int saved_processing_template_decl = processing_template_decl; + processing_template_decl = 0; + r = tsubst_copy_and_build (r, /*args=*/NULL_TREE, + tf_error, /*in_decl=*/NULL_TREE, + /*function_p=*/false); + processing_template_decl = saved_processing_template_decl; + } + r = fold (r); + } } + return r; } -/* Substitute ARGS into the vector of template arguments T. */ +/* Substitute ARGS into the vector or list of template arguments T. */ static tree -tsubst_template_arg_vector (tree t, tree args, tsubst_flags_t complain) +tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl) { - int len = TREE_VEC_LENGTH (t), need_new = 0, i; - tree *elts = (tree *) alloca (len * sizeof (tree)); - - memset ((char *) elts, 0, len * sizeof (tree)); + int len = TREE_VEC_LENGTH (t); + int need_new = 0, i; + tree *elts = alloca (len * sizeof (tree)); for (i = 0; i < len; i++) { - if (TREE_VEC_ELT (t, i) != NULL_TREE - && TREE_CODE (TREE_VEC_ELT (t, i)) == TREE_VEC) - elts[i] = tsubst_template_arg_vector (TREE_VEC_ELT (t, i), - args, complain); + tree orig_arg = TREE_VEC_ELT (t, i); + tree new_arg; + + if (TREE_CODE (orig_arg) == TREE_VEC) + new_arg = tsubst_template_args (orig_arg, args, complain, in_decl); else - elts[i] = maybe_fold_nontype_arg - (tsubst_expr (TREE_VEC_ELT (t, i), args, complain, - NULL_TREE)); + new_arg = tsubst_template_arg (orig_arg, args, complain, in_decl); - if (elts[i] == error_mark_node) + if (new_arg == error_mark_node) return error_mark_node; - if (elts[i] != TREE_VEC_ELT (t, i)) + elts[i] = new_arg; + if (new_arg != orig_arg) need_new = 1; } if (!need_new) return t; - + t = make_tree_vec (len); for (i = 0; i < len; i++) TREE_VEC_ELT (t, i) = elts[i]; @@ -5635,10 +5551,10 @@ tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain) tree parm_decl = TREE_VALUE (tuple); parm_decl = tsubst (parm_decl, args, complain, NULL_TREE); - default_value = tsubst_expr (default_value, args, - complain, NULL_TREE); - tuple = build_tree_list (maybe_fold_nontype_arg (default_value), - parm_decl); + default_value = tsubst_template_arg (default_value, args, + complain, NULL_TREE); + + tuple = build_tree_list (default_value, parm_decl); TREE_VEC_ELT (new_vec, i) = tuple; } @@ -5684,12 +5600,10 @@ tsubst_aggr_type (tree t, /* First, determine the context for the type we are looking up. */ - if (TYPE_CONTEXT (t) != NULL_TREE) - context = tsubst_aggr_type (TYPE_CONTEXT (t), args, - complain, + context = TYPE_CONTEXT (t); + if (context) + context = tsubst_aggr_type (context, args, complain, in_decl, /*entering_scope=*/1); - else - context = NULL_TREE; /* Then, figure out what arguments are appropriate for the type we are trying to find. For example, given: @@ -5700,8 +5614,8 @@ tsubst_aggr_type (tree t, and supposing that we are instantiating f<int, double>, then our ARGS will be {int, double}, but, when looking up S we only want {double}. */ - argvec = tsubst_template_arg_vector (TYPE_TI_ARGS (t), args, - complain); + argvec = tsubst_template_args (TYPE_TI_ARGS (t), args, + complain, in_decl); if (argvec == error_mark_node) return error_mark_node; @@ -5817,10 +5731,10 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) : DECL_TI_ARGS (DECL_TEMPLATE_RESULT (t)); tree full_args; - full_args = tsubst_template_arg_vector (tmpl_args, args, - complain); + full_args = tsubst_template_args (tmpl_args, args, + complain, in_decl); - /* tsubst_template_arg_vector doesn't copy the vector if + /* tsubst_template_args doesn't copy the vector if nothing changed. But, *something* should have changed. */ my_friendly_assert (full_args != tmpl_args, 0); @@ -5867,6 +5781,8 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) else { tree new_decl = tsubst (decl, args, complain, in_decl); + if (new_decl == error_mark_node) + return error_mark_node; DECL_TEMPLATE_RESULT (r) = new_decl; DECL_TI_TEMPLATE (new_decl) = r; @@ -5888,14 +5804,10 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) if (PRIMARY_TEMPLATE_P (t)) DECL_PRIMARY_TEMPLATE (r) = r; - /* We don't partially instantiate partial specializations. */ - if (TREE_CODE (decl) == TYPE_DECL) - break; - - /* Record this partial instantiation. */ - register_specialization (r, t, - DECL_TI_ARGS (DECL_TEMPLATE_RESULT (r))); - + if (TREE_CODE (decl) != TYPE_DECL) + /* Record this non-type partial instantiation. */ + register_specialization (r, t, + DECL_TI_ARGS (DECL_TEMPLATE_RESULT (r))); } break; @@ -5931,10 +5843,9 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) specialization, and the complete set of arguments used to specialize R. */ gen_tmpl = most_general_template (DECL_TI_TEMPLATE (t)); - argvec - = tsubst_template_arg_vector (DECL_TI_ARGS - (DECL_TEMPLATE_RESULT (gen_tmpl)), - args, complain); + argvec = tsubst_template_args (DECL_TI_ARGS + (DECL_TEMPLATE_RESULT (gen_tmpl)), + args, complain, in_decl); /* Check to see if we already have this specialization. */ spec = retrieve_specialization (gen_tmpl, argvec); @@ -5993,10 +5904,10 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) }; Here, the DECL_TI_TEMPLATE for the friend declaration - will be a LOOKUP_EXPR or an IDENTIFIER_NODE. We are - being called from tsubst_friend_function, and we want - only to create a new decl (R) with appropriate types so - that we can call determine_specialization. */ + will be an IDENTIFIER_NODE. We are being called from + tsubst_friend_function, and we want only to create a + new decl (R) with appropriate types so that we can call + determine_specialization. */ gen_tmpl = NULL_TREE; } @@ -6007,8 +5918,7 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) else member = 1; ctx = tsubst_aggr_type (DECL_CONTEXT (t), args, - complain, t, - /*entering_scope=*/1); + complain, t, /*entering_scope=*/1); } else { @@ -6109,7 +6019,8 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) clone_function_decl (r, /*update_method_vec_p=*/0); } else if (IDENTIFIER_OPNAME_P (DECL_NAME (r))) - grok_op_properties (r, DECL_FRIEND_P (r)); + grok_op_properties (r, DECL_FRIEND_P (r), + (complain & tf_error) != 0); } break; @@ -6122,11 +6033,14 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) TREE_TYPE (r) = type; c_apply_type_quals_to_decl (cp_type_quals (type), r); - if (TREE_CODE (DECL_INITIAL (r)) != TEMPLATE_PARM_INDEX) - DECL_INITIAL (r) = TREE_TYPE (r); - else - DECL_INITIAL (r) = tsubst (DECL_INITIAL (r), args, - complain, in_decl); + if (DECL_INITIAL (r)) + { + if (TREE_CODE (DECL_INITIAL (r)) != TEMPLATE_PARM_INDEX) + DECL_INITIAL (r) = TREE_TYPE (r); + else + DECL_INITIAL (r) = tsubst (DECL_INITIAL (r), args, + complain, in_decl); + } DECL_CONTEXT (r) = NULL_TREE; @@ -6157,6 +6071,8 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) case USING_DECL: { r = copy_node (t); + /* It is not a dependent using decl any more. */ + TREE_TYPE (r) = void_type_node; DECL_INITIAL (r) = tsubst_copy (DECL_INITIAL (t), args, complain, in_decl); TREE_CHAIN (r) = NULL_TREE; @@ -6221,7 +6137,13 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) r = copy_decl (t); if (TREE_CODE (r) == VAR_DECL) - type = complete_type (type); + { + type = complete_type (type); + DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r) + = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t); + } + else if (DECL_SELF_REFERENCE_P (t)) + SET_DECL_SELF_REFERENCE_P (r); TREE_TYPE (r) = type; c_apply_type_quals_to_decl (cp_type_quals (type), r); DECL_CONTEXT (r) = ctx; @@ -6383,8 +6305,8 @@ tsubst_function_type (tree t, return error_mark_node; } - fntype = build_cplus_method_type (r, return_type, TREE_CHAIN - (arg_types)); + fntype = build_method_type_directly (r, return_type, + TREE_CHAIN (arg_types)); } fntype = cp_build_qualified_type_real (fntype, TYPE_QUALS (t), complain); fntype = build_type_attribute_variant (fntype, TYPE_ATTRIBUTES (t)); @@ -6460,8 +6382,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) type = IDENTIFIER_TYPE_VALUE (t); else type = TREE_TYPE (t); - if (type == unknown_type_node) - abort (); + + my_friendly_assert (type != unknown_type_node, 20030716); if (type && TREE_CODE (t) != FUNCTION_DECL && TREE_CODE (t) != TYPENAME_TYPE @@ -6507,12 +6429,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) { tree max, omax = TREE_OPERAND (TYPE_MAX_VALUE (t), 0); - max = tsubst_expr (omax, args, complain, in_decl); - if (max == error_mark_node) - return error_mark_node; - - /* See if we can reduce this expression to something simpler. */ - max = maybe_fold_nontype_arg (max); + /* The array dimension behaves like a non-type template arg, + in that we want to fold it as much as possible. */ + max = tsubst_template_arg (omax, args, complain, in_decl); if (!processing_template_decl) max = decl_constant_value (max); @@ -6756,7 +6675,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) } /* Otherwise, a vector of template arguments. */ - return tsubst_template_arg_vector (t, args, complain); + return tsubst_template_args (t, args, complain, in_decl); case POINTER_TYPE: case REFERENCE_TYPE: @@ -6841,21 +6760,28 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) } my_friendly_assert (TREE_CODE (type) != METHOD_TYPE, 20011231); if (TREE_CODE (type) == FUNCTION_TYPE) - /* This is really a method type. The cv qualifiers of the - this pointer should _not_ be determined by the cv - qualifiers of the class type. They should be held - somewhere in the FUNCTION_TYPE, but we don't do that at - the moment. Consider - typedef void (Func) () const; - - template <typename T1> void Foo (Func T1::*); - - */ - return build_cplus_method_type (TYPE_MAIN_VARIANT (r), - TREE_TYPE (type), - TYPE_ARG_TYPES (type)); + { + /* This is really a method type. The cv qualifiers of the + this pointer should _not_ be determined by the cv + qualifiers of the class type. They should be held + somewhere in the FUNCTION_TYPE, but we don't do that at + the moment. Consider + typedef void (Func) () const; + + template <typename T1> void Foo (Func T1::*); + + */ + tree method_type; + + method_type = build_method_type_directly (TYPE_MAIN_VARIANT (r), + TREE_TYPE (type), + TYPE_ARG_TYPES (type)); + return build_ptrmemfunc_type (build_pointer_type (method_type)); + } else - return build_offset_type (r, type); + return cp_build_qualified_type_real (build_ptrmem_type (r, type), + TYPE_QUALS (t), + complain); } case FUNCTION_TYPE: case METHOD_TYPE: @@ -7104,8 +7030,9 @@ tsubst_baselink (tree baselink, tree object_type, template_id_p = true; template_args = TREE_OPERAND (fns, 1); fns = TREE_OPERAND (fns, 0); - template_args = tsubst_copy_and_build (template_args, args, - complain, in_decl); + if (template_args) + template_args = tsubst_template_args (template_args, args, + complain, in_decl); } name = DECL_NAME (get_first_fn (fns)); baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1); @@ -7140,17 +7067,15 @@ tsubst_qualified_id (tree qualified_id, tree args, my_friendly_assert (TREE_CODE (qualified_id) == SCOPE_REF, 20030706); - /* Look up the qualified name. */ - scope = TREE_OPERAND (qualified_id, 0); - scope = tsubst (scope, args, complain, in_decl); - /* Figure out what name to look up. */ name = TREE_OPERAND (qualified_id, 1); if (TREE_CODE (name) == TEMPLATE_ID_EXPR) { is_template = true; - template_args = tsubst_copy_and_build (TREE_OPERAND (name, 1), - args, complain, in_decl); + template_args = TREE_OPERAND (name, 1); + if (template_args) + template_args = tsubst_template_args (template_args, args, + complain, in_decl); name = TREE_OPERAND (name, 0); } else @@ -7159,24 +7084,52 @@ tsubst_qualified_id (tree qualified_id, tree args, template_args = NULL_TREE; } - expr = tsubst_copy (name, args, complain, in_decl); - if (!BASELINK_P (name)) + /* Substitute into the qualifying scope. When there are no ARGS, we + are just trying to simplify a non-dependent expression. In that + case the qualifying scope may be dependent, and, in any case, + substituting will not help. */ + scope = TREE_OPERAND (qualified_id, 0); + if (args) { - expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0); - if (DECL_P (expr)) - check_accessibility_of_qualified_id (expr, - /*object_type=*/NULL_TREE, - scope); + scope = tsubst (scope, args, complain, in_decl); + expr = tsubst_copy (name, args, complain, in_decl); } + else + expr = name; + my_friendly_assert (!dependent_type_p (scope), 20030729); + + if (!BASELINK_P (name) && !DECL_P (expr)) + { + expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0, false); + if (TREE_CODE (TREE_CODE (expr) == TEMPLATE_DECL + ? DECL_TEMPLATE_RESULT (expr) : expr) == TYPE_DECL) + { + if (complain & tf_error) + error ("`%E' names a type, but a non-type is expected", + qualified_id); + return error_mark_node; + } + } + + if (DECL_P (expr)) + check_accessibility_of_qualified_id (expr, /*object_type=*/NULL_TREE, + scope); + /* Remember that there was a reference to this entity. */ if (DECL_P (expr)) - mark_used (expr); + { + mark_used (expr); + if (!args && TREE_CODE (expr) == VAR_DECL) + expr = DECL_INITIAL (expr); + } if (is_template) - lookup_template_function (expr, template_args); + expr = lookup_template_function (expr, template_args); - if (TYPE_P (scope)) + if (expr == error_mark_node && complain & tf_error) + qualified_name_lookup_error (scope, TREE_OPERAND (qualified_id, 1)); + else if (TYPE_P (scope)) { expr = (adjust_result_of_qualified_name_lookup (expr, scope, current_class_type)); @@ -7215,8 +7168,9 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (DECL_TEMPLATE_PARM_P (t)) return tsubst_copy (DECL_INITIAL (t), args, complain, in_decl); - if (!DECL_CONTEXT (t)) - /* This is a global enumeration constant. */ + /* There is no need to substitute into namespace-scope + enumerators. */ + if (DECL_NAMESPACE_SCOPE_P (t)) return t; /* Unfortunately, we cannot just call lookup_name here. @@ -7300,25 +7254,6 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) /* Ordinary template template argument. */ return t; - case LOOKUP_EXPR: - { - /* We must tsubst into a LOOKUP_EXPR in case the names to - which it refers is a conversion operator; in that case the - name will change. We avoid making unnecessary copies, - however. */ - - tree id = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl); - - if (id != TREE_OPERAND (t, 0)) - { - r = build_nt (LOOKUP_EXPR, id); - LOOKUP_EXPR_GLOBAL (r) = LOOKUP_EXPR_GLOBAL (t); - t = r; - } - - return t; - } - case CAST_EXPR: case REINTERPRET_CAST_EXPR: case CONST_CAST_EXPR: @@ -7389,7 +7324,6 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) case ROUND_DIV_EXPR: case EXACT_DIV_EXPR: case BIT_AND_EXPR: - case BIT_ANDTC_EXPR: case BIT_IOR_EXPR: case BIT_XOR_EXPR: case TRUNC_MOD_EXPR: @@ -7439,8 +7373,10 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (!processing_template_decl) { tree stmt_expr = begin_stmt_expr (); - tsubst_expr (STMT_EXPR_STMT (t), args, complain, in_decl); - return finish_stmt_expr (stmt_expr); + + tsubst_expr (STMT_EXPR_STMT (t), args, + complain | tf_stmt_expr_cmpd, in_decl); + return finish_stmt_expr (stmt_expr, false); } return t; @@ -7479,12 +7415,14 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) case TEMPLATE_ID_EXPR: { /* Substituted template arguments */ - tree targs = tsubst_copy (TREE_OPERAND (t, 1), args, complain, - in_decl); + tree fn = TREE_OPERAND (t, 0); + tree targs = TREE_OPERAND (t, 1); - maybe_fold_nontype_args (targs); - return lookup_template_function - (tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl), targs); + fn = tsubst_copy (fn, args, complain, in_decl); + if (targs) + targs = tsubst_template_args (targs, args, complain, in_decl); + + return lookup_template_function (fn, targs); } case TREE_LIST: @@ -7565,7 +7503,10 @@ static tree tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) { tree stmt, tmp; + tsubst_flags_t stmt_expr + = complain & (tf_stmt_expr_cmpd | tf_stmt_expr_body); + complain ^= stmt_expr; if (t == NULL_TREE || t == error_mark_node) return t; @@ -7573,7 +7514,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) return tsubst_copy (t, args, complain, in_decl); if (!STATEMENT_CODE_P (TREE_CODE (t))) - return tsubst_copy_and_build (t, args, complain, in_decl); + return tsubst_copy_and_build (t, args, complain, in_decl, + /*function_p=*/false); switch (TREE_CODE (t)) { @@ -7590,10 +7532,18 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) break; case EXPR_STMT: - prep_stmt (t); - finish_expr_stmt (tsubst_expr (EXPR_STMT_EXPR (t), - args, complain, in_decl)); - break; + { + tree r; + + prep_stmt (t); + + r = tsubst_expr (EXPR_STMT_EXPR (t), args, complain, in_decl); + if (stmt_expr & tf_stmt_expr_body && !TREE_CHAIN (t)) + finish_stmt_expr_expr (r); + else + finish_expr_stmt (r); + break; + } case USING_STMT: prep_stmt (t); @@ -7614,11 +7564,16 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) { tree scope = DECL_INITIAL (decl); tree name = DECL_NAME (decl); + tree decl; scope = tsubst_expr (scope, args, complain, in_decl); - do_local_using_decl (lookup_qualified_name (scope, - name, - /*is_type_p=*/0)); + decl = lookup_qualified_name (scope, name, + /*is_type_p=*/false, + /*complain=*/false); + if (decl == error_mark_node) + qualified_name_lookup_error (scope, name); + else + do_local_using_decl (decl); } else { @@ -7642,7 +7597,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) else { maybe_push_decl (decl); - if (DECL_PRETTY_FUNCTION_P (decl)) + if (TREE_CODE (decl) == VAR_DECL + && DECL_PRETTY_FUNCTION_P (decl)) { /* For __PRETTY_FUNCTION__ we have to adjust the initializer. */ @@ -7740,12 +7696,14 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) else stmt = begin_compound_stmt (COMPOUND_STMT_NO_SCOPE (t)); - tsubst_expr (COMPOUND_BODY (t), args, complain, in_decl); + tsubst_expr (COMPOUND_BODY (t), args, + complain | ((stmt_expr & tf_stmt_expr_cmpd) << 1), + in_decl); if (COMPOUND_STMT_BODY_BLOCK (t)) finish_function_body (stmt); else - finish_compound_stmt (COMPOUND_STMT_NO_SCOPE (t), stmt); + finish_compound_stmt (stmt); } break; @@ -7878,18 +7836,40 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) abort (); } - return tsubst_expr (TREE_CHAIN (t), args, complain, in_decl); + return tsubst_expr (TREE_CHAIN (t), args, complain | stmt_expr, in_decl); +} + +/* T is a postfix-expression that is not being used in a function + call. Return the substituted version of T. */ + +static tree +tsubst_non_call_postfix_expression (tree t, tree args, + tsubst_flags_t complain, + tree in_decl) +{ + if (TREE_CODE (t) == SCOPE_REF) + t = tsubst_qualified_id (t, args, complain, in_decl, + /*done=*/false, /*address_p=*/false); + else + t = tsubst_copy_and_build (t, args, complain, in_decl, + /*function_p=*/false); + + return t; } /* Like tsubst but deals with expressions and performs semantic - analysis. */ + analysis. FUNCTION_P is true if T is the "F" in "F (ARGS)". */ tree tsubst_copy_and_build (tree t, tree args, tsubst_flags_t complain, - tree in_decl) + tree in_decl, + bool function_p) { +#define RECUR(NODE) \ + tsubst_copy_and_build (NODE, args, complain, in_decl, /*function_p=*/false) + tree op1; if (t == NULL_TREE || t == error_mark_node) @@ -7897,45 +7877,53 @@ tsubst_copy_and_build (tree t, switch (TREE_CODE (t)) { + case USING_DECL: + t = DECL_NAME (t); + /* Fallthrough. */ case IDENTIFIER_NODE: - if (IDENTIFIER_TYPENAME_P (t)) - { - tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl); - return do_identifier (mangle_conv_op_name_for_type (new_type), - NULL_TREE); - } - else - return do_identifier (t, NULL_TREE); - - case LOOKUP_EXPR: { - if (LOOKUP_EXPR_GLOBAL (t)) - { - tree token - = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl); - return do_scoped_id (token, IDENTIFIER_GLOBAL_VALUE (token)); - } - else + tree decl; + cp_id_kind idk; + tree qualifying_class; + bool non_constant_expression_p; + const char *error_msg; + + if (IDENTIFIER_TYPENAME_P (t)) { - t = do_identifier - (tsubst_copy - (TREE_OPERAND (t, 0), args, complain, in_decl), - NULL_TREE); - if (TREE_CODE (t) == ALIAS_DECL) - t = DECL_INITIAL (t); - return t; + tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl); + t = mangle_conv_op_name_for_type (new_type); } + + /* Look up the name. */ + decl = lookup_name (t, 0); + + /* By convention, expressions use ERROR_MARK_NODE to indicate + failure, not NULL_TREE. */ + if (decl == NULL_TREE) + decl = error_mark_node; + + decl = finish_id_expression (t, decl, NULL_TREE, + &idk, + &qualifying_class, + /*constant_expression_p=*/false, + /*allow_non_constant_expression_p=*/false, + &non_constant_expression_p, + &error_msg); + if (error_msg) + error (error_msg); + if (!function_p && TREE_CODE (decl) == IDENTIFIER_NODE) + decl = unqualified_name_lookup_error (decl); + return decl; } case TEMPLATE_ID_EXPR: { tree object; - tree template - = tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, - in_decl); - tree targs - = tsubst_copy_and_build (TREE_OPERAND (t, 1), args, complain, - in_decl); + tree template = RECUR (TREE_OPERAND (t, 0)); + tree targs = TREE_OPERAND (t, 1); + + if (targs) + targs = tsubst_template_args (targs, args, complain, in_decl); if (TREE_CODE (template) == COMPONENT_REF) { @@ -7954,46 +7942,37 @@ tsubst_copy_and_build (tree t, } case INDIRECT_REF: - return build_x_indirect_ref - (tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl), - "unary *"); + return build_x_indirect_ref (RECUR (TREE_OPERAND (t, 0)), "unary *"); case CAST_EXPR: return build_functional_cast (tsubst (TREE_TYPE (t), args, complain, in_decl), - tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl)); + RECUR (TREE_OPERAND (t, 0))); case REINTERPRET_CAST_EXPR: return build_reinterpret_cast (tsubst (TREE_TYPE (t), args, complain, in_decl), - tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl)); + RECUR (TREE_OPERAND (t, 0))); case CONST_CAST_EXPR: return build_const_cast (tsubst (TREE_TYPE (t), args, complain, in_decl), - tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl)); + RECUR (TREE_OPERAND (t, 0))); case DYNAMIC_CAST_EXPR: return build_dynamic_cast (tsubst (TREE_TYPE (t), args, complain, in_decl), - tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl)); + RECUR (TREE_OPERAND (t, 0))); case STATIC_CAST_EXPR: return build_static_cast (tsubst (TREE_TYPE (t), args, complain, in_decl), - tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl)); + RECUR (TREE_OPERAND (t, 0))); case POSTDECREMENT_EXPR: case POSTINCREMENT_EXPR: - op1 = TREE_OPERAND (t, 0); - if (TREE_CODE (op1) == SCOPE_REF) - op1 = tsubst_qualified_id (TREE_OPERAND (t, 0), - args, complain, - in_decl, - /*done=*/false, - /*address_p=*/false); - else - op1 = tsubst_copy_and_build (op1, args, complain, in_decl); + op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0), + args, complain, in_decl); return build_x_unary_op (TREE_CODE (t), op1); case PREDECREMENT_EXPR: @@ -8005,10 +7984,7 @@ tsubst_copy_and_build (tree t, case CONVERT_EXPR: /* Unary + */ case REALPART_EXPR: case IMAGPART_EXPR: - return (build_x_unary_op - (TREE_CODE (t), - tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, - in_decl))); + return build_x_unary_op (TREE_CODE (t), RECUR (TREE_OPERAND (t, 0))); case ADDR_EXPR: op1 = TREE_OPERAND (t, 0); @@ -8016,7 +7992,10 @@ tsubst_copy_and_build (tree t, op1 = tsubst_qualified_id (op1, args, complain, in_decl, /*done=*/true, /*address_p=*/true); else - op1 = tsubst_copy_and_build (op1, args, complain, in_decl); + op1 = tsubst_non_call_postfix_expression (op1, args, complain, + in_decl); + if (TREE_CODE (op1) == LABEL_DECL) + return finish_label_address_expr (DECL_NAME (op1)); return build_x_unary_op (ADDR_EXPR, op1); case PLUS_EXPR: @@ -8028,7 +8007,6 @@ tsubst_copy_and_build (tree t, case ROUND_DIV_EXPR: case EXACT_DIV_EXPR: case BIT_AND_EXPR: - case BIT_ANDTC_EXPR: case BIT_IOR_EXPR: case BIT_XOR_EXPR: case TRUNC_MOD_EXPR: @@ -8050,15 +8028,11 @@ tsubst_copy_and_build (tree t, case LT_EXPR: case GT_EXPR: case MEMBER_REF: + case DOTSTAR_EXPR: return build_x_binary_op (TREE_CODE (t), - tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl), - tsubst_copy_and_build (TREE_OPERAND (t, 1), args, complain, in_decl)); - - case DOTSTAR_EXPR: - return build_m_component_ref - (tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl), - tsubst_copy_and_build (TREE_OPERAND (t, 1), args, complain, in_decl)); + RECUR (TREE_OPERAND (t, 0)), + RECUR (TREE_OPERAND (t, 1))); case SCOPE_REF: return tsubst_qualified_id (t, args, complain, in_decl, /*done=*/true, @@ -8068,24 +8042,14 @@ tsubst_copy_and_build (tree t, if (tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl) == NULL_TREE) /* new-type-id */ - return build_nt - (ARRAY_REF, NULL_TREE, - tsubst_copy_and_build (TREE_OPERAND (t, 1), args, complain, - in_decl)); + return build_nt (ARRAY_REF, NULL_TREE, RECUR (TREE_OPERAND (t, 1))); - op1 = TREE_OPERAND (t, 0); - if (TREE_CODE (op1) == SCOPE_REF) - op1 = tsubst_qualified_id (op1, args, complain, in_decl, - /*done=*/false, /*address_p=*/false); - else - op1 = tsubst_copy_and_build (op1, args, complain, in_decl); + op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0), + args, complain, in_decl); /* Remember that there was a reference to this entity. */ if (DECL_P (op1)) mark_used (op1); - return grok_array_decl (op1, - tsubst_copy_and_build (TREE_OPERAND (t, 1), - args, complain, - in_decl)); + return grok_array_decl (op1, RECUR (TREE_OPERAND (t, 1))); case SIZEOF_EXPR: case ALIGNOF_EXPR: @@ -8101,27 +8065,23 @@ tsubst_copy_and_build (tree t, else { ++skip_evaluation; - op1 = tsubst_copy_and_build (op1, args, complain, in_decl); + op1 = RECUR (op1); --skip_evaluation; } - if (TREE_CODE (t) == SIZEOF_EXPR) - return finish_sizeof (op1); + if (TYPE_P (op1)) + return cxx_sizeof_or_alignof_type (op1, TREE_CODE (t), true); else - return finish_alignof (op1); + return cxx_sizeof_or_alignof_expr (op1, TREE_CODE (t)); case MODOP_EXPR: return build_x_modify_expr - (tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl), + (RECUR (TREE_OPERAND (t, 0)), TREE_CODE (TREE_OPERAND (t, 1)), - tsubst_copy_and_build (TREE_OPERAND (t, 2), args, complain, in_decl)); + RECUR (TREE_OPERAND (t, 2))); case ARROW_EXPR: - op1 = TREE_OPERAND (t, 0); - if (TREE_CODE (op1) == SCOPE_REF) - op1 = tsubst_qualified_id (op1, args, complain, in_decl, - /*done=*/false, /*address_p=*/false); - else - op1 = tsubst_copy_and_build (op1, args, complain, in_decl); + op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0), + args, complain, in_decl); /* Remember that there was a reference to this entity. */ if (DECL_P (op1)) mark_used (op1); @@ -8129,38 +8089,33 @@ tsubst_copy_and_build (tree t, case NEW_EXPR: return build_new - (tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl), - tsubst_copy_and_build (TREE_OPERAND (t, 1), args, complain, in_decl), - tsubst_copy_and_build (TREE_OPERAND (t, 2), args, complain, in_decl), + (RECUR (TREE_OPERAND (t, 0)), + RECUR (TREE_OPERAND (t, 1)), + RECUR (TREE_OPERAND (t, 2)), NEW_EXPR_USE_GLOBAL (t)); case DELETE_EXPR: return delete_sanity - (tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl), - tsubst_copy_and_build (TREE_OPERAND (t, 1), args, complain, in_decl), + (RECUR (TREE_OPERAND (t, 0)), + RECUR (TREE_OPERAND (t, 1)), DELETE_EXPR_USE_VEC (t), DELETE_EXPR_USE_GLOBAL (t)); case COMPOUND_EXPR: - return (build_x_compound_expr - (tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, - in_decl), - tsubst_copy_and_build (TREE_OPERAND (t, 1), args, complain, - in_decl))); + return build_x_compound_expr (RECUR (TREE_OPERAND (t, 0)), + RECUR (TREE_OPERAND (t, 1))); case CALL_EXPR: { tree function; tree call_args; - tree koenig_name; bool qualified_p; + bool koenig_p; function = TREE_OPERAND (t, 0); - if (TREE_CODE (function) == LOOKUP_EXPR - && !LOOKUP_EXPR_GLOBAL (function)) - koenig_name = TREE_OPERAND (function, 0); - else - koenig_name = NULL_TREE; + /* When we parsed the expression, we determined whether or + not Koenig lookup should be performed. */ + koenig_p = KOENIG_LOOKUP_P (t); if (TREE_CODE (function) == SCOPE_REF) { qualified_p = true; @@ -8174,24 +8129,31 @@ tsubst_copy_and_build (tree t, && (TREE_CODE (TREE_OPERAND (function, 1)) == SCOPE_REF)); function = tsubst_copy_and_build (function, args, complain, - in_decl); - function = convert_from_reference (function); + in_decl, + !qualified_p); + if (BASELINK_P (function)) + qualified_p = true; + } + + call_args = RECUR (TREE_OPERAND (t, 1)); + + if (koenig_p + && (is_overloaded_fn (function) + || DECL_P (function) + || TREE_CODE (function) == IDENTIFIER_NODE)) + function = perform_koenig_lookup (function, call_args); + + if (TREE_CODE (function) == IDENTIFIER_NODE) + { + unqualified_name_lookup_error (function); + return error_mark_node; } /* Remember that there was a reference to this entity. */ if (DECL_P (function)) mark_used (function); - call_args = tsubst_copy_and_build (TREE_OPERAND (t, 1), args, - complain, in_decl); - - if (BASELINK_P (function)) - qualified_p = 1; - - if (call_args != NULL_TREE && koenig_name) - function = lookup_arg_dependent (koenig_name, - function, - call_args); + function = convert_from_reference (function); if (TREE_CODE (function) == OFFSET_REF) return build_offset_ref_call_from_tree (function, call_args); @@ -8202,20 +8164,21 @@ tsubst_copy_and_build (tree t, call_args, NULL_TREE, qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL)); return finish_call_expr (function, call_args, - /*disallow_virtual=*/qualified_p); + /*disallow_virtual=*/qualified_p, + koenig_p); } case COND_EXPR: return build_x_conditional_expr - (tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl), - tsubst_copy_and_build (TREE_OPERAND (t, 1), args, complain, in_decl), - tsubst_copy_and_build (TREE_OPERAND (t, 2), args, complain, in_decl)); + (RECUR (TREE_OPERAND (t, 0)), + RECUR (TREE_OPERAND (t, 1)), + RECUR (TREE_OPERAND (t, 2))); case PSEUDO_DTOR_EXPR: return finish_pseudo_destructor_expr - (tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl), - tsubst_copy_and_build (TREE_OPERAND (t, 1), args, complain, in_decl), - tsubst_copy_and_build (TREE_OPERAND (t, 2), args, complain, in_decl)); + (RECUR (TREE_OPERAND (t, 0)), + RECUR (TREE_OPERAND (t, 1)), + RECUR (TREE_OPERAND (t, 2))); case TREE_LIST: { @@ -8226,13 +8189,13 @@ tsubst_copy_and_build (tree t, purpose = TREE_PURPOSE (t); if (purpose) - purpose = tsubst_copy_and_build (purpose, args, complain, in_decl); + purpose = RECUR (purpose); value = TREE_VALUE (t); if (value) - value = tsubst_copy_and_build (value, args, complain, in_decl); + value = RECUR (value); chain = TREE_CHAIN (t); if (chain && chain != void_type_node) - chain = tsubst_copy_and_build (chain, args, complain, in_decl); + chain = RECUR (chain); if (purpose == TREE_PURPOSE (t) && value == TREE_VALUE (t) && chain == TREE_CHAIN (t)) @@ -8245,13 +8208,8 @@ tsubst_copy_and_build (tree t, tree object; tree member; - object = TREE_OPERAND (t, 0); - if (TREE_CODE (object) == SCOPE_REF) - object = tsubst_qualified_id (object, args, complain, in_decl, - /*done=*/false, /*address_p=*/false); - else - object = tsubst_copy_and_build (object, args, complain, in_decl); - + object = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0), + args, complain, in_decl); /* Remember that there was a reference to this entity. */ if (DECL_P (object)) mark_used (object); @@ -8286,27 +8244,28 @@ tsubst_copy_and_build (tree t, scope is. */ tmpl = TREE_OPERAND (TREE_OPERAND (member, 1), 0); args = TREE_OPERAND (TREE_OPERAND (member, 1), 1); - member = lookup_qualified_name (TREE_OPERAND (member, 0), - tmpl, - /*is_type=*/0); + member = lookup_qualified_name (TREE_OPERAND (member, 0), tmpl, + /*is_type_p=*/false, + /*complain=*/false); if (BASELINK_P (member)) BASELINK_FUNCTIONS (member) = build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member), args); else { - error ("`%D' is not a member of `%T'", - tmpl, TREE_TYPE (object)); + qualified_name_lookup_error (TREE_TYPE (object), tmpl); return error_mark_node; } } + else if (TREE_CODE (member) == FIELD_DECL) + return finish_non_static_data_member (member, object, NULL_TREE); return finish_class_member_access_expr (object, member); } case THROW_EXPR: return build_throw - (tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl)); + (RECUR (TREE_OPERAND (t, 0))); case CONSTRUCTOR: { @@ -8332,9 +8291,8 @@ tsubst_copy_and_build (tree t, tree value = TREE_VALUE (elts); if (purpose && purpose_p) - purpose - = tsubst_copy_and_build (purpose, args, complain, in_decl); - value = tsubst_copy_and_build (value, args, complain, in_decl); + purpose = RECUR (purpose); + value = RECUR (value); r = tree_cons (purpose, value, r); } @@ -8348,10 +8306,7 @@ tsubst_copy_and_build (tree t, case TYPEID_EXPR: { - tree operand_0 - = tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, - in_decl); - + tree operand_0 = RECUR (TREE_OPERAND (t, 0)); if (TYPE_P (operand_0)) return get_typeid (operand_0); return build_typeid (operand_0); @@ -8371,14 +8326,15 @@ tsubst_copy_and_build (tree t, return convert_from_reference (t); case VA_ARG_EXPR: - return build_x_va_arg - (tsubst_copy_and_build - (TREE_OPERAND (t, 0), args, complain, in_decl), - tsubst_copy (TREE_TYPE (t), args, complain, in_decl)); + return build_x_va_arg (RECUR (TREE_OPERAND (t, 0)), + tsubst_copy (TREE_TYPE (t), args, complain, + in_decl)); default: return tsubst_copy (t, args, complain, in_decl); } + +#undef RECUR } /* Verify that the instantiated ARGS are valid. For type arguments, @@ -8497,18 +8453,23 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain) complain)) return error_mark_node; - /* Make sure that we can see identifiers, and compute access - correctly. The desired FUNCTION_DECL for FNDECL may or may not be - created earlier. Let push_access_scope_real figure that out. */ - push_access_scope_real - (gen_tmpl, targ_ptr, tsubst (DECL_CONTEXT (gen_tmpl), targ_ptr, - complain, gen_tmpl)); + /* We are building a FUNCTION_DECL, during which the access of its + parameters and return types have to be checked. However this + FUNCTION_DECL which is the desired context for access checking + is not built yet. We solve this chicken-and-egg problem by + deferring all checks until we have the FUNCTION_DECL. */ + push_deferring_access_checks (dk_deferred); /* substitute template parameters */ fndecl = tsubst (DECL_TEMPLATE_RESULT (gen_tmpl), targ_ptr, complain, gen_tmpl); - pop_access_scope (gen_tmpl); + /* Now we know the specialization, compute access previously + deferred. */ + push_access_scope (fndecl); + perform_deferred_access_checks (); + pop_access_scope (fndecl); + pop_deferring_access_checks (); /* The DECL_TI_TEMPLATE should always be the immediate parent template, not the most general template. */ @@ -8605,6 +8566,7 @@ fn_type_unification (tree fn, template results in an invalid type, type deduction fails. */ int i; tree converted_args; + bool incomplete; converted_args = (coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (fn), @@ -8613,12 +8575,22 @@ fn_type_unification (tree fn, if (converted_args == error_mark_node) return 1; + /* Substitute the explicit args into the function type. This is + necessary so that, for instance, explicitly declared function + arguments can match null pointed constants. If we were given + an incomplete set of explicit args, we must not do semantic + processing during substitution as we could create partial + instantiations. */ + incomplete = NUM_TMPL_ARGS (explicit_targs) != NUM_TMPL_ARGS (targs); + processing_template_decl += incomplete; fntype = tsubst (fntype, converted_args, tf_none, NULL_TREE); + processing_template_decl -= incomplete; + if (fntype == error_mark_node) return 1; /* Place the explicitly specified arguments in TARGS. */ - for (i = 0; i < TREE_VEC_LENGTH (targs); i++) + for (i = NUM_TMPL_ARGS (converted_args); i--;) TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (converted_args, i); } @@ -8795,9 +8767,7 @@ type_unification_real (tree tparms, my_friendly_assert (TREE_CODE (tparms) == TREE_VEC, 289); my_friendly_assert (xparms == NULL_TREE || TREE_CODE (xparms) == TREE_LIST, 290); - /* ARGS could be NULL. */ - if (xargs) - my_friendly_assert (TREE_CODE (xargs) == TREE_LIST, 291); + my_friendly_assert (!xargs || TREE_CODE (xargs) == TREE_LIST, 291); my_friendly_assert (ntparms > 0, 292); switch (strict) @@ -8962,9 +8932,15 @@ resolve_overloaded_unification (tree tparms, { tree tempargs = copy_node (targs); int good = 0; + bool addr_p; if (TREE_CODE (arg) == ADDR_EXPR) - arg = TREE_OPERAND (arg, 0); + { + arg = TREE_OPERAND (arg, 0); + addr_p = true; + } + else + addr_p = false; if (TREE_CODE (arg) == COMPONENT_REF) /* Handle `&x' where `x' is some static or non-static member @@ -9000,10 +8976,8 @@ resolve_overloaded_unification (tree tparms, if (subargs) { 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, - strict, sub_strict); + good += try_one_overload (tparms, targs, tempargs, parm, + elem, strict, sub_strict, addr_p); } } } @@ -9011,14 +8985,9 @@ resolve_overloaded_unification (tree tparms, || TREE_CODE (arg) == FUNCTION_DECL) { for (; arg; arg = OVL_NEXT (arg)) - { - tree type = TREE_TYPE (OVL_CURRENT (arg)); - if (TREE_CODE (type) == METHOD_TYPE) - type = build_ptrmemfunc_type (build_pointer_type (type)); - good += try_one_overload (tparms, targs, tempargs, parm, - type, - strict, sub_strict); - } + good += try_one_overload (tparms, targs, tempargs, parm, + TREE_TYPE (OVL_CURRENT (arg)), + strict, sub_strict, addr_p); } else abort (); @@ -9047,6 +9016,9 @@ resolve_overloaded_unification (tree tparms, /* Subroutine of resolve_overloaded_unification; does deduction for a single overload. Fills TARGS with any deduced arguments, or error_mark_node if different overloads deduce different arguments for a given parm. + ADDR_P is true if the expression for which deduction is being + performed was of the form "& fn" rather than simply "fn". + Returns 1 on success. */ static int @@ -9056,7 +9028,8 @@ try_one_overload (tree tparms, tree parm, tree arg, unification_kind_t strict, - int sub_strict) + int sub_strict, + bool addr_p) { int nargs; tree tempargs; @@ -9072,6 +9045,11 @@ try_one_overload (tree tparms, if (uses_template_parms (arg)) return 1; + if (TREE_CODE (arg) == METHOD_TYPE) + arg = build_ptrmemfunc_type (build_pointer_type (arg)); + else if (addr_p) + arg = build_pointer_type (arg); + sub_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg); /* We don't copy orig_targs for this because if we have already deduced @@ -9535,12 +9513,6 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) } else { - /* If ARG is an offset type, we're trying to unify '*T' with - 'U C::*', which is ill-formed. See the comment in the - POINTER_TYPE case about this ugliness. */ - if (TREE_CODE (arg) == OFFSET_TYPE) - return 1; - /* If PARM is `const T' and ARG is only `int', we don't have a match unless we are allowing additional qualification. If ARG is `const int' and PARM is just `T' that's OK; @@ -9641,18 +9613,6 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) level of pointers. */ strict |= (strict_in & UNIFY_ALLOW_DERIVED); - if (TREE_CODE (TREE_TYPE (parm)) == OFFSET_TYPE - && TREE_CODE (TREE_TYPE (arg)) == OFFSET_TYPE) - { - /* Avoid getting confused about cv-quals; don't recurse here. - Pointers to members should really be just OFFSET_TYPE, not - this two-level nonsense... */ - - parm = TREE_TYPE (parm); - arg = TREE_TYPE (arg); - goto offset; - } - return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg), strict); } @@ -9806,7 +9766,6 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) DEDUCE_EXACT, 0, -1); case OFFSET_TYPE: - offset: if (TREE_CODE (arg) != OFFSET_TYPE) return 1; if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm), @@ -9946,6 +9905,10 @@ more_specialized (tree pat1, tree pat2, int deduce, int len) tree targs; int winner = 0; + /* If template argument deduction succeeds, we substitute the + resulting arguments into non-deduced contexts. While doing that, + we must be aware that we may encounter dependent types. */ + ++processing_template_decl; targs = get_bindings_real (pat1, DECL_TEMPLATE_RESULT (pat2), NULL_TREE, 0, deduce, len); if (targs) @@ -9955,6 +9918,7 @@ more_specialized (tree pat1, tree pat2, int deduce, int len) NULL_TREE, 0, deduce, len); if (targs) ++winner; + --processing_template_decl; return winner; } @@ -9963,21 +9927,24 @@ more_specialized (tree pat1, tree pat2, int deduce, int len) 1 if PAT1 is more specialized than PAT2 as described in [temp.class.order]. -1 if PAT2 is more specialized than PAT1. - 0 if neither is more specialized. */ + 0 if neither is more specialized. + + FULL_ARGS is the full set of template arguments that triggers this + partial ordering. */ int -more_specialized_class (tree pat1, tree pat2) +more_specialized_class (tree pat1, tree pat2, tree full_args) { tree targs; int winner = 0; targs = get_class_bindings (TREE_VALUE (pat1), TREE_PURPOSE (pat1), - TREE_PURPOSE (pat2)); + add_outermost_template_args (full_args, TREE_PURPOSE (pat2))); if (targs) --winner; targs = get_class_bindings (TREE_VALUE (pat2), TREE_PURPOSE (pat2), - TREE_PURPOSE (pat1)); + add_outermost_template_args (full_args, TREE_PURPOSE (pat1))); if (targs) ++winner; @@ -10050,7 +10017,7 @@ get_bindings_real (tree fn, /* For most uses, we want to check the return type. */ -tree +static tree get_bindings (tree fn, tree decl, tree explicit_args) { return get_bindings_real (fn, decl, explicit_args, 1, DEDUCE_EXACT, -1); @@ -10205,8 +10172,8 @@ most_general_template (tree decl) /* Look for more and more general templates. */ while (DECL_TEMPLATE_INFO (decl)) { - /* The DECL_TI_TEMPLATE can be a LOOKUP_EXPR or IDENTIFIER_NODE - in some cases. (See cp-tree.h for details.) */ + /* The DECL_TI_TEMPLATE can be an IDENTIFIER_NODE in some cases. + (See cp-tree.h for details.) */ if (TREE_CODE (DECL_TI_TEMPLATE (decl)) != TEMPLATE_DECL) break; @@ -10258,7 +10225,7 @@ most_specialized_class (tree tmpl, tree args) t = TREE_CHAIN (t); for (; t; t = TREE_CHAIN (t)) { - fate = more_specialized_class (champ, t); + fate = more_specialized_class (champ, t, args); if (fate == 1) ; else @@ -10275,7 +10242,7 @@ most_specialized_class (tree tmpl, tree args) for (t = list; t && t != champ; t = TREE_CHAIN (t)) { - fate = more_specialized_class (champ, t); + fate = more_specialized_class (champ, t, args); if (fate != 1) return error_mark_node; } @@ -10595,7 +10562,7 @@ regenerate_decl_from_template (tree decl, tree tmpl) tree args; tree code_pattern; tree new_decl; - int unregistered; + bool unregistered; args = DECL_TI_ARGS (decl); code_pattern = DECL_TEMPLATE_RESULT (tmpl); @@ -10606,14 +10573,18 @@ regenerate_decl_from_template (tree decl, tree tmpl) instantiation of a specialization, which it isn't: it's a full instantiation. */ gen_tmpl = most_general_template (tmpl); - push_access_scope_real (gen_tmpl, args, DECL_CONTEXT (decl)); - unregistered = unregister_specialization (decl, gen_tmpl); + unregistered = reregister_specialization (decl, gen_tmpl, + /*new_spec=*/NULL_TREE); /* If the DECL was not unregistered then something peculiar is happening: we created a specialization but did not call register_specialization for it. */ my_friendly_assert (unregistered, 0); + /* Make sure that we can see identifiers, and compute access + correctly. */ + push_access_scope (decl); + /* Do the substitution to get the new declaration. */ new_decl = tsubst (code_pattern, args, tf_error, NULL_TREE); @@ -10775,10 +10746,14 @@ instantiate_decl (tree d, int defer_ok) timevar_push (TV_PARSE); - /* We may be in the middle of deferred access check. Disable - it now. */ + /* We may be in the middle of deferred access check. Disable it now. */ push_deferring_access_checks (dk_no_deferred); + /* Our caller does not expect collection to happen, which it might if + we decide to compile the function to rtl now. Arrange for a new + gc context to be created if so. */ + function_depth++; + /* Set TD to the template whose DECL_TEMPLATE_RESULT is the pattern for the instantiation. */ td = template_for_substitution (d); @@ -11023,6 +10998,7 @@ out: input_location = saved_loc; pop_deferring_access_checks (); pop_tinst_level (); + function_depth--; timevar_pop (TV_PARSE); @@ -11185,18 +11161,20 @@ tsubst_enum (tree tag, tree newtag, tree args) for (e = TYPE_VALUES (tag); e; e = TREE_CHAIN (e)) { tree value; - + tree decl; + + decl = TREE_VALUE (e); /* 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)), + value = tsubst_expr (DECL_INITIAL (decl), args, tf_error | tf_warning, NULL_TREE); /* Give this enumeration constant the correct access. */ - set_current_access_from_decl (TREE_VALUE (e)); + set_current_access_from_decl (decl); /* Actually build the enumerator itself. */ - build_enumerator (TREE_PURPOSE (e), value, newtag); + build_enumerator (DECL_NAME (decl), value, newtag); } finish_enum (newtag); @@ -11303,9 +11281,7 @@ invalid_nontype_parm_type_p (tree type, tsubst_flags_t complain) return 0; else if (POINTER_TYPE_P (type)) return 0; - else if (TYPE_PTRMEM_P (type)) - return 0; - else if (TYPE_PTRMEMFUNC_P (type)) + else if (TYPE_PTR_TO_MEMBER_P (type)) return 0; else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM) return 0; @@ -11342,7 +11318,7 @@ dependent_type_p_r (tree type) dependent. */ type = TYPE_MAIN_VARIANT (type); /* -- a compound type constructed from any dependent type. */ - if (TYPE_PTRMEM_P (type) || TYPE_PTRMEMFUNC_P (type)) + if (TYPE_PTR_TO_MEMBER_P (type)) return (dependent_type_p (TYPE_PTRMEM_CLASS_TYPE (type)) || dependent_type_p (TYPE_PTRMEM_POINTED_TO_TYPE (type))); @@ -11376,25 +11352,24 @@ dependent_type_p_r (tree type) return true; return dependent_type_p (TREE_TYPE (type)); } + /* -- a template-id in which either the template name is a template - parameter or any of the template arguments is a dependent type or - an expression that is type-dependent or value-dependent. - - This language seems somewhat confused; for example, it does not - discuss template template arguments. Therefore, we use the - definition for dependent template arguments in [temp.dep.temp]. */ - if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INFO (type) - && (dependent_template_id_p - (CLASSTYPE_TI_TEMPLATE (type), - CLASSTYPE_TI_ARGS (type)))) + parameter ... */ + if (TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM) return true; - else if (TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM) + /* ... or any of the template arguments is a dependent type or + an expression that is type-dependent or value-dependent. */ + else if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INFO (type) + && (any_dependent_template_arguments_p + (INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type))))) return true; + /* All TYPEOF_TYPEs are dependent; if the argument of the `typeof' expression is not type-dependent, then it should already been have resolved. */ if (TREE_CODE (type) == TYPEOF_TYPE) return true; + /* The standard does not specifically mention types that are local to template functions or local classes, but they should be considered dependent too. For example: @@ -11447,6 +11422,40 @@ dependent_type_p (tree type) return TYPE_DEPENDENT_P (type); } +/* Returns TRUE if EXPRESSION is dependent, according to CRITERION. */ + +static bool +dependent_scope_ref_p (tree expression, bool criterion (tree)) +{ + tree scope; + tree name; + + my_friendly_assert (TREE_CODE (expression) == SCOPE_REF, 20030714); + + if (!TYPE_P (TREE_OPERAND (expression, 0))) + return true; + + scope = TREE_OPERAND (expression, 0); + name = TREE_OPERAND (expression, 1); + + /* [temp.dep.expr] + + An id-expression is type-dependent if it contains a + nested-name-specifier that contains a class-name that names a + dependent type. */ + /* The suggested resolution to Core Issue 2 implies that if the + qualifying type is the current class, then we must peek + inside it. */ + if (DECL_P (name) + && currently_open_class (scope) + && !criterion (name)) + return false; + if (dependent_type_p (scope)) + return true; + + return false; +} + /* Returns TRUE if the EXPRESSION is value-dependent, in the sense of [temp.dep.constexpr] */ @@ -11457,7 +11466,7 @@ value_dependent_expression_p (tree expression) return false; /* A name declared with a dependent type. */ - if (TREE_CODE (expression) == LOOKUP_EXPR + if (TREE_CODE (expression) == IDENTIFIER_NODE || (DECL_P (expression) && type_dependent_expression_p (expression))) return true; @@ -11510,6 +11519,8 @@ value_dependent_expression_p (tree expression) return dependent_type_p (expression); return type_dependent_expression_p (expression); } + if (TREE_CODE (expression) == SCOPE_REF) + return dependent_scope_ref_p (expression, value_dependent_expression_p); /* A constant expression is value-dependent if any subexpression is value-dependent. */ if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (expression)))) @@ -11555,6 +11566,13 @@ type_dependent_expression_p (tree expression) if (!processing_template_decl) return false; + if (expression == error_mark_node) + return false; + + /* An unresolved name is always dependent. */ + if (TREE_CODE (expression) == IDENTIFIER_NODE) + return true; + /* Some expression forms are never type-dependent. */ if (TREE_CODE (expression) == PSEUDO_DTOR_EXPR || TREE_CODE (expression) == SIZEOF_EXPR @@ -11593,24 +11611,37 @@ type_dependent_expression_p (tree expression) return dependent_type_p (type); } + if (TREE_CODE (expression) == SCOPE_REF + && dependent_scope_ref_p (expression, + type_dependent_expression_p)) + return true; + if (TREE_CODE (expression) == FUNCTION_DECL && DECL_LANG_SPECIFIC (expression) && DECL_TEMPLATE_INFO (expression) - && (dependent_template_id_p - (DECL_TI_TEMPLATE (expression), - INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (expression))))) + && (any_dependent_template_arguments_p + (INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (expression))))) return true; if (TREE_TYPE (expression) == unknown_type_node) { if (TREE_CODE (expression) == ADDR_EXPR) return type_dependent_expression_p (TREE_OPERAND (expression, 0)); + if (TREE_CODE (expression) == COMPONENT_REF) + { + if (type_dependent_expression_p (TREE_OPERAND (expression, 0))) + return true; + expression = TREE_OPERAND (expression, 1); + if (TREE_CODE (expression) == IDENTIFIER_NODE) + return false; + } + if (TREE_CODE (expression) == BASELINK) expression = BASELINK_FUNCTIONS (expression); if (TREE_CODE (expression) == TEMPLATE_ID_EXPR) { - if (any_dependent_template_arguments_p (TREE_OPERAND (expression, - 1))) + if (any_dependent_template_arguments_p + (TREE_OPERAND (expression, 1))) return true; expression = TREE_OPERAND (expression, 0); } @@ -11638,7 +11669,9 @@ any_type_dependent_arguments_p (tree args) { while (args) { - if (type_dependent_expression_p (TREE_VALUE (args))) + tree arg = TREE_VALUE (args); + + if (type_dependent_expression_p (arg)) return true; args = TREE_CHAIN (args); } @@ -11669,29 +11702,14 @@ dependent_template_arg_p (tree arg) bool any_dependent_template_arguments_p (tree args) { + int i; + if (!args) return false; - my_friendly_assert (TREE_CODE (args) == TREE_LIST - || TREE_CODE (args) == TREE_VEC, - 20030707); - - if (TREE_CODE (args) == TREE_LIST) - { - while (args) - { - if (dependent_template_arg_p (TREE_VALUE (args))) - return true; - args = TREE_CHAIN (args); - } - } - else - { - int i; - for (i = 0; i < TREE_VEC_LENGTH (args); ++i) - if (dependent_template_arg_p (TREE_VEC_ELT (args, i))) - return true; - } + for (i = 0; i < TREE_VEC_LENGTH (args); ++i) + if (dependent_template_arg_p (TREE_VEC_ELT (args, i))) + return true; return false; } @@ -11787,8 +11805,7 @@ resolve_typename_type (tree type, bool only_current_p) args = TREE_OPERAND (TYPENAME_TYPE_FULLNAME (type), 1); /* Instantiate the template. */ type = lookup_template_class (tmpl, args, NULL_TREE, NULL_TREE, - /*entering_scope=*/0, - tf_error); + /*entering_scope=*/0, tf_error | tf_user); } else type = error_mark_node; @@ -11816,6 +11833,25 @@ build_non_dependent_expr (tree expr) types. */ if (TREE_CODE (expr) == OVERLOAD) return expr; + /* Preserve string constants; conversions from string constants to + "char *" are allowed, even though normally a "const char *" + cannot be used to initialize a "char *". */ + if (TREE_CODE (expr) == STRING_CST) + return expr; + + if (TREE_CODE (expr) == COND_EXPR) + return build (COND_EXPR, + TREE_TYPE (expr), + TREE_OPERAND (expr, 0), + build_non_dependent_expr (TREE_OPERAND (expr, 1)), + build_non_dependent_expr (TREE_OPERAND (expr, 2))); + if (TREE_CODE (expr) == COMPOUND_EXPR + && !COMPOUND_EXPR_OVERLOADED (expr)) + return build (COMPOUND_EXPR, + TREE_TYPE (expr), + TREE_OPERAND (expr, 0), + build_non_dependent_expr (TREE_OPERAND (expr, 1))); + /* Otherwise, build a NON_DEPENDENT_EXPR. REFERENCE_TYPEs are not stripped for expressions in templates @@ -11830,7 +11866,7 @@ build_non_dependent_expr (tree expr) the expression so that mangling (say) "f<g>" inside the body of "f" works out correctly. Therefore, the REFERENCE_TYPE is stripped here. */ - return build (NON_DEPENDENT_EXPR, non_reference (TREE_TYPE (expr))); + return build1 (NON_DEPENDENT_EXPR, non_reference (TREE_TYPE (expr)), expr); } /* ARGS is a TREE_LIST of expressions as arguments to a function call. |