diff options
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r-- | gcc/cp/pt.c | 91 |
1 files changed, 68 insertions, 23 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 59543ca0dfa..28c295695e4 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -161,6 +161,7 @@ static int coerce_template_template_parms PROTO((tree, tree, int, static tree determine_specialization PROTO((tree, tree, tree *, int)); static int template_args_equal PROTO((tree, tree)); static void print_template_context PROTO((int)); +static int has_pvbases_p PROTO((tree, tree)); /* We use TREE_VECs to hold template arguments. If there is only one level of template arguments, then the TREE_VEC contains the @@ -2210,12 +2211,17 @@ check_default_tmpl_args (decl, parms, is_primary, is_partial) if (current_class_type && !TYPE_BEING_DEFINED (current_class_type) - && DECL_REAL_CONTEXT (decl) == current_class_type && DECL_LANG_SPECIFIC (decl) - && DECL_DEFINED_IN_CLASS_P (decl)) + /* If this is either a friend defined in the scope of the class + or a member function. */ + && DECL_CLASS_CONTEXT (decl) == current_class_type + /* And, if it was a member function, it really was defined in + the scope of the class. */ + && (!DECL_FUNCTION_MEMBER_P (decl) || DECL_DEFINED_IN_CLASS_P (decl))) /* We already checked these parameters when the template was - declared, so there's no need to do it again now. This is an - inline member function definition. */ + declared, so there's no need to do it again now. This function + was defined in class scope, but we're processing it's body now + that the class is complete. */ return; if (TREE_CODE (decl) != TYPE_DECL || is_partial || !is_primary) @@ -2781,18 +2787,14 @@ convert_nontype_argument (type, expr) 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_node (PTRMEM_CST); - TREE_TYPE (e) = type; - PTRMEM_CST_MEMBER (e) = PTRMEM_CST_MEMBER (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) @@ -3573,6 +3575,7 @@ maybe_get_template_decl_from_type_decl (decl) return (decl != NULL_TREE && TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl) + && CLASS_TYPE_P (TREE_TYPE (decl)) && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (decl))) ? CLASSTYPE_TI_TEMPLATE (TREE_TYPE (decl)) : decl; } @@ -4683,6 +4686,23 @@ tsubst_friend_class (friend_tmpl, args) return friend_type; } +static int +has_pvbases_p (t, pattern) + tree t, pattern; +{ + if (!TYPE_USES_VIRTUAL_BASECLASSES (t)) + return 0; + + if (TYPE_USES_PVBASES (pattern)) + return 1; + + for (t = CLASSTYPE_VBASECLASSES (t); t; t = TREE_CHAIN (t)) + if (TYPE_VIRTUAL_P (BINFO_TYPE (t))) + return 1; + + return 0; +} + tree instantiate_class_template (type) tree type; @@ -5033,6 +5053,13 @@ instantiate_class_template (type) } } + /* After we have calculated the bases, we can now compute whether we + have polymorphic vbases. This needs to happen before we + instantiate the methods, because the constructors may take + additional arguments. */ + if (flag_vtable_thunks >= 2) + TYPE_USES_PVBASES (type) = has_pvbases_p (type, pattern); + /* Set up the list (TYPE_METHODS) and vector (CLASSTYPE_METHOD_VEC) for this instantiation. */ for (t = TYPE_METHODS (pattern); t; t = TREE_CHAIN (t)) @@ -5714,9 +5741,17 @@ tsubst_decl (t, args, type, in_decl) SET_DECL_IMPLICIT_INSTANTIATION (r); register_specialization (r, gen_tmpl, argvec); + + if (DECL_CONSTRUCTOR_P (r) || DECL_DESTRUCTOR_P (r)) + { + maybe_retrofit_in_chrg (r); + grok_ctor_properties (ctx, r); + } + /* Set the mangled name for R. */ if (DECL_DESTRUCTOR_P (t)) - DECL_ASSEMBLER_NAME (r) = build_destructor_name (ctx); + DECL_ASSEMBLER_NAME (r) = + build_destructor_name (ctx, DECL_DESTRUCTOR_FOR_PVBASE_P (r)); else { /* Instantiations of template functions must be mangled @@ -5759,11 +5794,14 @@ tsubst_decl (t, args, type, in_decl) in_decl); } +#if 0 + /* This has now moved further up. */ if (DECL_CONSTRUCTOR_P (r)) { maybe_retrofit_in_chrg (r); grok_ctor_properties (ctx, r); } +#endif if (IDENTIFIER_OPNAME_P (DECL_NAME (r))) grok_op_properties (r, DECL_VIRTUAL_P (r), DECL_FRIEND_P (r)); } @@ -6128,6 +6166,11 @@ tsubst (t, 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); + if (!processing_template_decl && TREE_READONLY_DECL_P (max)) + max = decl_constant_value (max); + if (processing_template_decl /* When providing explicit arguments to a template function, but leaving some arguments for subsequent @@ -6540,6 +6583,8 @@ tsubst (t, args, complain, in_decl) } f = make_typename_type (ctx, f); + if (f == error_mark_node) + return f; return cp_build_qualified_type (f, CP_TYPE_QUALS (f) | CP_TYPE_QUALS (t)); @@ -8909,8 +8954,8 @@ do_decl_instantiation (declspecs, declarator, storage) No program shall both explicitly instantiate and explicitly specialize a template. */ - cp_error ("explicit instantiation of `%#D' after", result); - cp_error_at ("explicit specialization here", result); + cp_pedwarn ("explicit instantiation of `%#D' after", result); + cp_pedwarn_at ("explicit specialization here", result); return; } else if (DECL_EXPLICIT_INSTANTIATION (result)) @@ -8923,8 +8968,8 @@ do_decl_instantiation (declspecs, declarator, storage) We check DECL_INTERFACE_KNOWN so as not to complain when the first instantiation was `extern' and the second is not, and EXTERN_P for the opposite case. */ - if (DECL_INTERFACE_KNOWN (result) && !extern_p) - cp_error ("duplicate explicit instantiation of `%#D'", result); + if (DECL_INTERFACE_KNOWN (result) && !extern_p && !flag_use_repository) + cp_pedwarn ("duplicate explicit instantiation of `%#D'", result); /* If we've already instantiated the template, just return now. */ if (DECL_INTERFACE_KNOWN (result)) @@ -9051,8 +9096,8 @@ do_type_instantiation (t, storage) If CLASSTYPE_INTERFACE_ONLY, then the first explicit instantiation was `extern', and if EXTERN_P then the second is. Both cases are OK. */ - if (!CLASSTYPE_INTERFACE_ONLY (t) && !extern_p) - cp_error ("duplicate explicit instantiation of `%#T'", t); + if (!CLASSTYPE_INTERFACE_ONLY (t) && !extern_p && !flag_use_repository) + cp_pedwarn ("duplicate explicit instantiation of `%#T'", t); /* If we've already instantiated the template, just return now. */ if (!CLASSTYPE_INTERFACE_ONLY (t)) |