diff options
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r-- | gcc/cp/pt.c | 203 |
1 files changed, 123 insertions, 80 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 09d077ade06..7a331479d8b 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -158,7 +158,7 @@ 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_class (tree, tree); +static tree most_specialized_class (tree, tree, tsubst_flags_t); static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int); static tree tsubst_arg_types (tree, tree, tsubst_flags_t, tree); static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree); @@ -1566,31 +1566,43 @@ iterative_hash_template_arg (tree arg, hashval_t val) gcc_assert (seen_error ()); return val; + case CAST_EXPR: + case STATIC_CAST_EXPR: + case REINTERPRET_CAST_EXPR: + case CONST_CAST_EXPR: + case DYNAMIC_CAST_EXPR: + case NEW_EXPR: + val = iterative_hash_template_arg (TREE_TYPE (arg), val); + /* Now hash operands as usual. */ + break; + default: - switch (tclass) - { - case tcc_type: - if (TYPE_CANONICAL (arg)) - return iterative_hash_object (TYPE_HASH (TYPE_CANONICAL (arg)), - val); - else if (TREE_CODE (arg) == DECLTYPE_TYPE) - return iterative_hash_template_arg (DECLTYPE_TYPE_EXPR (arg), val); - /* Otherwise just compare the types during lookup. */ - return val; + break; + } - case tcc_declaration: - case tcc_constant: - return iterative_hash_expr (arg, val); + switch (tclass) + { + case tcc_type: + if (TYPE_CANONICAL (arg)) + return iterative_hash_object (TYPE_HASH (TYPE_CANONICAL (arg)), + val); + else if (TREE_CODE (arg) == DECLTYPE_TYPE) + return iterative_hash_template_arg (DECLTYPE_TYPE_EXPR (arg), val); + /* Otherwise just compare the types during lookup. */ + return val; - default: - gcc_assert (IS_EXPR_CODE_CLASS (tclass)); - { - unsigned n = TREE_OPERAND_LENGTH (arg); - for (i = 0; i < n; ++i) - val = iterative_hash_template_arg (TREE_OPERAND (arg, i), val); - return val; - } - } + case tcc_declaration: + case tcc_constant: + return iterative_hash_expr (arg, val); + + default: + gcc_assert (IS_EXPR_CODE_CLASS (tclass)); + { + unsigned n = TREE_OPERAND_LENGTH (arg); + for (i = 0; i < n; ++i) + val = iterative_hash_template_arg (TREE_OPERAND (arg, i), val); + return val; + } } gcc_unreachable (); return 0; @@ -2553,7 +2565,7 @@ check_explicit_specialization (tree declarator, definition, not in the original declaration. */ DECL_ARGUMENTS (result) = DECL_ARGUMENTS (decl); for (parm = DECL_ARGUMENTS (result); parm; - parm = TREE_CHAIN (parm)) + parm = DECL_CHAIN (parm)) DECL_CONTEXT (parm) = result; } return register_specialization (tmpl, gen_tmpl, targs, @@ -3831,6 +3843,7 @@ process_partial_specialization (tree decl) tree inner_args = INNERMOST_TEMPLATE_ARGS (specargs); tree main_inner_parms = DECL_INNERMOST_TEMPLATE_PARMS (maintmpl); tree inner_parms; + tree inst; int nargs = TREE_VEC_LENGTH (inner_args); int ntparms; int i; @@ -4045,6 +4058,22 @@ process_partial_specialization (tree decl) = tree_cons (specargs, inner_parms, DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)); TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)) = type; + + for (inst = DECL_TEMPLATE_INSTANTIATIONS (maintmpl); inst; + inst = TREE_CHAIN (inst)) + { + tree inst_type = TREE_VALUE (inst); + if (COMPLETE_TYPE_P (inst_type) + && CLASSTYPE_IMPLICIT_INSTANTIATION (inst_type)) + { + tree spec = most_specialized_class (inst_type, maintmpl, tf_none); + if (spec && TREE_TYPE (spec) == type) + permerror (input_location, + "partial specialization of %qT after instantiation " + "of %qT", type, inst_type); + } + } + return decl; } @@ -4417,7 +4446,7 @@ push_template_decl_real (tree decl, bool is_friend) TREE_VALUE (argtype) = error_mark_node; } - arg = TREE_CHAIN (arg); + arg = DECL_CHAIN (arg); argtype = TREE_CHAIN (argtype); } @@ -7749,7 +7778,7 @@ instantiate_class_template (tree type) /* Determine what specialization of the original template to instantiate. */ - t = most_specialized_class (type, templ); + t = most_specialized_class (type, templ, tf_warning_or_error); if (t == error_mark_node) { TYPE_BEING_DEFINED (type) = 1; @@ -7803,7 +7832,8 @@ instantiate_class_template (tree type) /* Set the input location to the most specialized template definition. This is needed if tsubsting causes an error. */ typedecl = TYPE_MAIN_DECL (pattern); - input_location = DECL_SOURCE_LOCATION (typedecl); + input_location = DECL_SOURCE_LOCATION (TYPE_NAME (type)) = + DECL_SOURCE_LOCATION (typedecl); TYPE_HAS_USER_CONSTRUCTOR (type) = TYPE_HAS_USER_CONSTRUCTOR (pattern); TYPE_HAS_NEW_OPERATOR (type) = TYPE_HAS_NEW_OPERATOR (pattern); @@ -8196,7 +8226,7 @@ instantiate_class_template (tree type) any member functions. We don't do this earlier because the default arguments may reference members of the class. */ if (!PRIMARY_TEMPLATE_P (templ)) - for (t = TYPE_METHODS (type); t; t = TREE_CHAIN (t)) + for (t = TYPE_METHODS (type); t; t = DECL_CHAIN (t)) if (TREE_CODE (t) == FUNCTION_DECL /* Implicitly generated member functions will not have template information; they are not instantiations, but instead are @@ -8261,7 +8291,7 @@ make_fnparm_pack (tree spec_parm) /* Fill in PARMVEC and PARMTYPEVEC with all of the parameters. */ parmvec = make_tree_vec (len); parmtypevec = make_tree_vec (len); - for (i = 0; i < len; i++, spec_parm = TREE_CHAIN (spec_parm)) + for (i = 0; i < len; i++, spec_parm = DECL_CHAIN (spec_parm)) { TREE_VEC_ELT (parmvec, i) = spec_parm; TREE_VEC_ELT (parmtypevec, i) = TREE_TYPE (spec_parm); @@ -8541,7 +8571,7 @@ get_pattern_parm (tree parm, tree tmpl) if (DECL_ARTIFICIAL (parm)) { for (patparm = DECL_ARGUMENTS (pattern); - patparm; patparm = TREE_CHAIN (patparm)) + patparm; patparm = DECL_CHAIN (patparm)) if (DECL_ARTIFICIAL (patparm) && DECL_NAME (parm) == DECL_NAME (patparm)) break; @@ -8936,7 +8966,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) RETURN (error_mark_node); r = copy_decl (t); - TREE_CHAIN (r) = NULL_TREE; + DECL_CHAIN (r) = NULL_TREE; TREE_TYPE (r) = new_type; DECL_TEMPLATE_RESULT (r) = build_decl (DECL_SOURCE_LOCATION (decl), @@ -8986,7 +9016,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) than the old one. */ r = copy_decl (t); gcc_assert (DECL_LANG_SPECIFIC (r) != 0); - TREE_CHAIN (r) = NULL_TREE; + DECL_CHAIN (r) = NULL_TREE; DECL_TEMPLATE_INFO (r) = build_template_info (t, args); @@ -9196,7 +9226,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) assigned to the instantiation. */ DECL_INTERFACE_KNOWN (r) = !TREE_PUBLIC (r); DECL_DEFER_OUTPUT (r) = 0; - TREE_CHAIN (r) = NULL_TREE; + DECL_CHAIN (r) = NULL_TREE; DECL_PENDING_INLINE_INFO (r) = 0; DECL_PENDING_INLINE_P (r) = 0; DECL_SAVED_TREE (r) = NULL_TREE; @@ -9395,12 +9425,12 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) /* Build a proper chain of parameters when substituting into a function parameter pack. */ if (prev_r) - TREE_CHAIN (prev_r) = r; + DECL_CHAIN (prev_r) = r; } - if (TREE_CHAIN (t)) - TREE_CHAIN (r) = tsubst (TREE_CHAIN (t), args, - complain, TREE_CHAIN (t)); + if (DECL_CHAIN (t)) + DECL_CHAIN (r) = tsubst (DECL_CHAIN (t), args, + complain, DECL_CHAIN (t)); /* FIRST_R contains the start of the chain we've built. */ r = first_r; @@ -9425,7 +9455,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) /*integral_constant_expression_p=*/true); /* We don't have to set DECL_CONTEXT here; it is set by finish_member_declaration. */ - TREE_CHAIN (r) = NULL_TREE; + DECL_CHAIN (r) = NULL_TREE; if (VOID_TYPE_P (type)) error ("instantiation of %q+D as type %qT", r, type); @@ -9452,7 +9482,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) else { r = copy_node (t); - TREE_CHAIN (r) = NULL_TREE; + DECL_CHAIN (r) = NULL_TREE; } break; @@ -9652,7 +9682,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) else register_local_specialization (r, t); - TREE_CHAIN (r) = NULL_TREE; + DECL_CHAIN (r) = NULL_TREE; apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), /*flags=*/0, @@ -9958,6 +9988,7 @@ tsubst_exception_specification (tree fntype, tree tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) { + enum tree_code code; tree type, r; if (t == NULL_TREE || t == error_mark_node @@ -9974,7 +10005,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (args == NULL_TREE) return t; - if (TREE_CODE (t) == IDENTIFIER_NODE) + code = TREE_CODE (t); + + if (code == IDENTIFIER_NODE) type = IDENTIFIER_TYPE_VALUE (t); else type = TREE_TYPE (t); @@ -10017,16 +10050,16 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) } if (type - && TREE_CODE (t) != TYPENAME_TYPE - && TREE_CODE (t) != TEMPLATE_TYPE_PARM - && TREE_CODE (t) != IDENTIFIER_NODE - && TREE_CODE (t) != FUNCTION_TYPE - && TREE_CODE (t) != METHOD_TYPE) + && code != TYPENAME_TYPE + && code != TEMPLATE_TYPE_PARM + && code != IDENTIFIER_NODE + && code != FUNCTION_TYPE + && code != METHOD_TYPE) type = tsubst (type, args, complain, in_decl); if (type == error_mark_node) return error_mark_node; - switch (TREE_CODE (t)) + switch (code) { case RECORD_TYPE: case UNION_TYPE: @@ -10156,7 +10189,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) }; */ return t; - if (TREE_CODE (t) == TEMPLATE_TYPE_PARM) + if (code == TEMPLATE_TYPE_PARM) { int quals; gcc_assert (TYPE_P (arg)); @@ -10166,7 +10199,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) return cp_build_qualified_type_real (arg, quals, complain | tf_ignore_bad_quals); } - else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM) + else if (code == BOUND_TEMPLATE_TEMPLATE_PARM) { /* We are processing a type constructed from a template template parameter. */ @@ -10205,7 +10238,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) /* If we get here, we must have been looking at a parm for a more deeply nested template. Make a new version of this template parameter, but with a lower level. */ - switch (TREE_CODE (t)) + switch (code) { case TEMPLATE_TYPE_PARM: case TEMPLATE_TEMPLATE_PARM: @@ -10215,7 +10248,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) r = tsubst (TYPE_MAIN_VARIANT (t), args, complain, in_decl); r = cp_build_qualified_type_real (r, cp_type_quals (t), - complain | (TREE_CODE (t) == TEMPLATE_TYPE_PARM + complain | (code == TEMPLATE_TYPE_PARM ? tf_ignore_bad_quals : 0)); } else @@ -10243,7 +10276,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) else TYPE_CANONICAL (r) = canonical_type_parameter (r); - if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM) + if (code == BOUND_TEMPLATE_TEMPLATE_PARM) { tree argvec = tsubst (TYPE_TI_ARGS (t), args, complain, in_decl); @@ -10314,14 +10347,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) case POINTER_TYPE: case REFERENCE_TYPE: { - enum tree_code code; - if (type == TREE_TYPE (t) && TREE_CODE (type) != METHOD_TYPE) return t; - code = TREE_CODE (t); - - /* [temp.deduct] Type deduction may fail for any of the following @@ -10506,7 +10534,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) return error_mark_node; return fold_build2_loc (input_location, - TREE_CODE (t), TREE_TYPE (t), e1, e2); + code, TREE_TYPE (t), e1, e2); } case NEGATE_EXPR: @@ -10516,7 +10544,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (e == error_mark_node) return error_mark_node; - return fold_build1_loc (input_location, TREE_CODE (t), TREE_TYPE (t), e); + return fold_build1_loc (input_location, code, TREE_TYPE (t), e); } case TYPENAME_TYPE: @@ -10672,9 +10700,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) case TYPE_ARGUMENT_PACK: case NONTYPE_ARGUMENT_PACK: { - tree r = TYPE_P (t) - ? cxx_make_type (TREE_CODE (t)) - : make_node (TREE_CODE (t)); + tree r = TYPE_P (t) ? cxx_make_type (code) : make_node (code); tree packed_out = tsubst_template_args (ARGUMENT_PACK_ARGS (t), args, @@ -10684,7 +10710,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) /* For template nontype argument packs, also substitute into the type. */ - if (TREE_CODE (t) == NONTYPE_ARGUMENT_PACK) + if (code == NONTYPE_ARGUMENT_PACK) TREE_TYPE (r) = tsubst (TREE_TYPE (t), args, complain, in_decl); return r; @@ -10692,8 +10718,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) break; default: - sorry ("use of %qs in template", - tree_code_name [(int) TREE_CODE (t)]); + sorry ("use of %qs in template", tree_code_name [(int) code]); return error_mark_node; } } @@ -10737,6 +10762,8 @@ tsubst_baselink (tree baselink, tree object_type, if (IDENTIFIER_TYPENAME_P (name)) name = mangle_conv_op_name_for_type (optype); baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1); + if (!baselink) + return error_mark_node; /* If lookup found a single function, mark it as used at this point. (If it lookup found multiple functions the one selected @@ -11312,8 +11339,13 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) gcc_unreachable (); case OFFSET_REF: - mark_used (TREE_OPERAND (t, 1)); - return t; + r = build2 + (code, tsubst (TREE_TYPE (t), args, complain, in_decl), + tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl), + tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl)); + PTRMEM_OK_P (r) = PTRMEM_OK_P (t); + mark_used (TREE_OPERAND (r, 1)); + return r; case EXPR_PACK_EXPANSION: error ("invalid use of pack expansion expression"); @@ -12500,15 +12532,24 @@ tsubst_copy_and_build (tree t, ret = build_offset_ref_call_from_tree (function, &call_args); else if (TREE_CODE (function) == COMPONENT_REF) { - if (!BASELINK_P (TREE_OPERAND (function, 1))) + tree instance = TREE_OPERAND (function, 0); + tree fn = TREE_OPERAND (function, 1); + + if (processing_template_decl + && (type_dependent_expression_p (instance) + || (!BASELINK_P (fn) + && TREE_CODE (fn) != FIELD_DECL) + || type_dependent_expression_p (fn) + || any_type_dependent_arguments_p (call_args))) + ret = build_nt_call_vec (function, call_args); + else if (!BASELINK_P (fn)) ret = finish_call_expr (function, &call_args, /*disallow_virtual=*/false, /*koenig_p=*/false, complain); else ret = (build_new_method_call - (TREE_OPERAND (function, 0), - TREE_OPERAND (function, 1), + (instance, fn, &call_args, NULL_TREE, qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL, /*fn_p=*/NULL, @@ -13121,7 +13162,7 @@ instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain) instantiate all the alternate entry points as well. We do this by cloning the instantiation of the main entry point, not by instantiating the template clones. */ - if (TREE_CHAIN (gen_tmpl) && DECL_CLONED_FUNCTION_P (TREE_CHAIN (gen_tmpl))) + if (DECL_CHAIN (gen_tmpl) && DECL_CLONED_FUNCTION_P (DECL_CHAIN (gen_tmpl))) clone_function_decl (fndecl, /*update_method_vec_p=*/0); return fndecl; @@ -15972,7 +16013,7 @@ most_general_template (tree decl) returned. */ static tree -most_specialized_class (tree type, tree tmpl) +most_specialized_class (tree type, tree tmpl, tsubst_flags_t complain) { tree list = NULL_TREE; tree t; @@ -16092,6 +16133,8 @@ most_specialized_class (tree type, tree tmpl) { const char *str; char *spaces = NULL; + if (!(complain & tf_error)) + return error_mark_node; error ("ambiguous class template instantiation for %q#T", type); str = TREE_CHAIN (list) ? _("candidates are:") : _("candidate is:"); for (t = list; t; t = TREE_CHAIN (t)) @@ -16390,12 +16433,12 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain) interpretation is that it should be an explicit instantiation. */ if (! static_p) - for (tmp = TYPE_METHODS (t); tmp; tmp = TREE_CHAIN (tmp)) + for (tmp = TYPE_METHODS (t); tmp; tmp = DECL_CHAIN (tmp)) if (TREE_CODE (tmp) == FUNCTION_DECL && DECL_TEMPLATE_INSTANTIATION (tmp)) instantiate_class_member (tmp, extern_p); - for (tmp = TYPE_FIELDS (t); tmp; tmp = TREE_CHAIN (tmp)) + for (tmp = TYPE_FIELDS (t); tmp; tmp = DECL_CHAIN (tmp)) if (TREE_CODE (tmp) == VAR_DECL && DECL_TEMPLATE_INSTANTIATION (tmp)) instantiate_class_member (tmp, extern_p); @@ -16483,8 +16526,8 @@ regenerate_decl_from_template (tree decl, tree tmpl) DECL_ATTRIBUTES (decl_parm) = attributes; cplus_decl_attributes (&decl_parm, attributes, /*flags=*/0); } - decl_parm = TREE_CHAIN (decl_parm); - pattern_parm = TREE_CHAIN (pattern_parm); + decl_parm = DECL_CHAIN (decl_parm); + pattern_parm = DECL_CHAIN (pattern_parm); } /* Merge any parameters that match with the function parameter pack. */ @@ -16516,7 +16559,7 @@ regenerate_decl_from_template (tree decl, tree tmpl) DECL_ATTRIBUTES (decl_parm) = attributes; cplus_decl_attributes (&decl_parm, attributes, /*flags=*/0); } - decl_parm = TREE_CHAIN (decl_parm); + decl_parm = DECL_CHAIN (decl_parm); } } /* Merge additional specifiers from the CODE_PATTERN. */ @@ -16926,8 +16969,8 @@ instantiate_decl (tree d, int defer_ok, while (tmpl_parm && !FUNCTION_PARAMETER_PACK_P (tmpl_parm)) { register_local_specialization (spec_parm, tmpl_parm); - tmpl_parm = TREE_CHAIN (tmpl_parm); - spec_parm = TREE_CHAIN (spec_parm); + tmpl_parm = DECL_CHAIN (tmpl_parm); + spec_parm = DECL_CHAIN (spec_parm); } if (tmpl_parm && FUNCTION_PARAMETER_PACK_P (tmpl_parm)) { @@ -16935,7 +16978,7 @@ instantiate_decl (tree d, int defer_ok, TMPL_PARM, then move on. */ tree argpack = make_fnparm_pack (spec_parm); register_local_specialization (argpack, tmpl_parm); - tmpl_parm = TREE_CHAIN (tmpl_parm); + tmpl_parm = DECL_CHAIN (tmpl_parm); spec_parm = NULL_TREE; } gcc_assert (!spec_parm); |