diff options
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r-- | gcc/cp/pt.c | 133 |
1 files changed, 100 insertions, 33 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 7025deff788..28b9b6471bc 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -34,7 +34,11 @@ Boston, MA 02111-1307, USA. */ #include "tree.h" #include "pointer-set.h" #include "flags.h" +/* APPLE LOCAL mainline */ +#include "c-common.h" #include "cp-tree.h" +/* APPLE LOCAL mainline */ +#include "cp-objcp-common.h" #include "tree-inline.h" #include "decl.h" #include "output.h" @@ -1353,8 +1357,8 @@ determine_specialization (tree template_id, /* Count the number of template headers specified for this specialization. */ header_count = 0; - for (b = current_binding_level; - b->kind == sk_template_parms || b->kind == sk_template_spec; + for (b = current_binding_level; + b->kind == sk_template_parms; b = b->level_chain) ++header_count; @@ -1423,6 +1427,14 @@ determine_specialization (tree template_id, if (header_count && header_count != template_count + 1) continue; + /* Check that the number of template arguments at the + innermost level for DECL is the same as for FN. */ + if (current_binding_level->kind == sk_template_parms + && !current_binding_level->explicit_spec_p + && (TREE_VEC_LENGTH (DECL_INNERMOST_TEMPLATE_PARMS (fn)) + != TREE_VEC_LENGTH (TREE_VALUE (current_template_parms)))) + continue; + /* See whether this function might be a specialization of this template. */ targs = get_bindings (fn, decl, explicit_targs); @@ -4596,6 +4608,8 @@ lookup_template_class (tree d1, = TREE_PRIVATE (TYPE_STUB_DECL (template_type)); TREE_PROTECTED (type_decl) = TREE_PROTECTED (TYPE_STUB_DECL (template_type)); + DECL_IN_SYSTEM_HEADER (type_decl) + = DECL_IN_SYSTEM_HEADER (template); /* Set up the template information. We have to figure out which template is the immediate parent if this is a full @@ -4988,7 +5002,10 @@ push_tinst_level (tree d) return 0; } - new = make_tinst_level (d, input_location); + new = make_node (TINST_LEVEL); + TINST_DECL (new) = d; + TINST_LOCATION (new) = input_location; + TINST_IN_SYSTEM_HEADER_P (new) = in_system_header; TREE_CHAIN (new) = current_tinst_level; current_tinst_level = new; @@ -5013,6 +5030,7 @@ pop_tinst_level (void) /* Restore the filename and line number stashed away when we started this instantiation. */ input_location = TINST_LOCATION (old); + in_system_header = TINST_IN_SYSTEM_HEADER_P (old); current_tinst_level = TREE_CHAIN (old); --tinst_depth; ++tinst_level_tick; @@ -5491,7 +5509,9 @@ instantiate_class_template (tree 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)); + typedecl = TYPE_MAIN_DECL (type); + input_location = DECL_SOURCE_LOCATION (typedecl); + in_system_header = DECL_IN_SYSTEM_HEADER (typedecl); TYPE_HAS_CONSTRUCTOR (type) = TYPE_HAS_CONSTRUCTOR (pattern); TYPE_HAS_NEW_OPERATOR (type) = TYPE_HAS_NEW_OPERATOR (pattern); @@ -5805,7 +5825,6 @@ instantiate_class_template (tree type) the class itself. This puts error messages involving generated implicit functions at a predictable point, and the same point that would be used for non-template classes. */ - typedecl = TYPE_MAIN_DECL (type); input_location = DECL_SOURCE_LOCATION (typedecl); unreverse_member_declarations (type); @@ -6468,8 +6487,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) SET_DECL_TEMPLATE_PARM_P (r); type = tsubst (TREE_TYPE (t), args, complain, in_decl); + type = type_decays_to (type); TREE_TYPE (r) = type; - c_apply_type_quals_to_decl (cp_type_quals (type), r); + cp_apply_type_quals_to_decl (cp_type_quals (type), r); if (DECL_INITIAL (r)) { @@ -6499,7 +6519,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) if (type == error_mark_node) return error_mark_node; TREE_TYPE (r) = type; - c_apply_type_quals_to_decl (cp_type_quals (type), r); + cp_apply_type_quals_to_decl (cp_type_quals (type), r); /* We don't have to set DECL_CONTEXT here; it is set by finish_member_declaration. */ @@ -6599,7 +6619,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) 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); + cp_apply_type_quals_to_decl (cp_type_quals (type), r); DECL_CONTEXT (r) = ctx; /* Clear out the mangled name and RTL for the instantiation. */ SET_DECL_ASSEMBLER_NAME (r, NULL_TREE); @@ -7218,22 +7238,18 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) gcc_assert (TREE_CODE (type) != METHOD_TYPE); 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::*); - - */ + /* The type of the implicit object parameter gets its + cv-qualifiers from the FUNCTION_TYPE. */ tree method_type; - - method_type = build_method_type_directly (TYPE_MAIN_VARIANT (r), + tree this_type = cp_build_qualified_type (TYPE_MAIN_VARIANT (r), + cp_type_quals (type)); + tree memptr; + method_type = build_method_type_directly (this_type, TREE_TYPE (type), TYPE_ARG_TYPES (type)); - return build_ptrmemfunc_type (build_pointer_type (method_type)); + memptr = build_ptrmemfunc_type (build_pointer_type (method_type)); + return cp_build_qualified_type_real (memptr, cp_type_quals (t), + complain); } else return cp_build_qualified_type_real (build_ptrmem_type (r, type), @@ -8839,6 +8855,18 @@ tsubst_copy_and_build (tree t, return t; default: + /* APPLE LOCAL begin mainline */ + /* Handle Objective-C++ constructs, if appropriate. */ + { + tree subst + = objcp_tsubst_copy_and_build (t, args, complain, + in_decl, /*function_p=*/false); + + if (subst) + return subst; + } + /* APPLE LOCAL end mainline */ + return tsubst_copy (t, args, complain, in_decl); } @@ -9342,17 +9370,14 @@ type_unification_real (tree tparms, else type = arg; - if (strict == DEDUCE_EXACT || strict == DEDUCE_ORDER) - { - if (same_type_p (parm, type)) - continue; - } - else - /* It might work; we shouldn't check now, because we might - get into infinite recursion. Overload resolution will - handle it. */ + /* APPLE LOCAL begin mainline 4.1 2005-06-17 4122333 */ + if (same_type_p (parm, type)) continue; - + if (strict != DEDUCE_EXACT && strict != DEDUCE_ORDER + && can_convert_arg (parm, type, TYPE_P (arg) ? NULL_TREE : arg)) + continue; + /* APPLE LOCAL end mainline 4.1 2005-06-17 4122333 */ + return 1; } @@ -10251,6 +10276,37 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) DEDUCE_EXACT, 0, -1); case OFFSET_TYPE: + /* Unify a pointer to member with a pointer to member function, which + deduces the type of the member as a function type. */ + if (TYPE_PTRMEMFUNC_P (arg)) + { + tree method_type; + tree fntype; + cp_cv_quals cv_quals; + + /* Check top-level cv qualifiers */ + if (!check_cv_quals_for_unify (UNIFY_ALLOW_NONE, arg, parm)) + return 1; + + if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm), + TYPE_PTRMEMFUNC_OBJECT_TYPE (arg), UNIFY_ALLOW_NONE)) + return 1; + + /* Determine the type of the function we are unifying against. */ + method_type = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (arg)); + fntype = + build_function_type (TREE_TYPE (method_type), + TREE_CHAIN (TYPE_ARG_TYPES (method_type))); + + /* Extract the cv-qualifiers of the member function from the + implicit object parameter and place them on the function + type to be restored later. */ + cv_quals = + cp_type_quals(TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (method_type)))); + fntype = build_qualified_type (fntype, cv_quals); + return unify (tparms, targs, TREE_TYPE (parm), fntype, strict); + } + if (TREE_CODE (arg) != OFFSET_TYPE) return 1; if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm), @@ -11057,13 +11113,21 @@ regenerate_decl_from_template (tree decl, tree tmpl) while (decl_parm) { tree parm_type; + tree attributes; if (DECL_NAME (decl_parm) != DECL_NAME (pattern_parm)) DECL_NAME (decl_parm) = DECL_NAME (pattern_parm); parm_type = tsubst (TREE_TYPE (pattern_parm), args, tf_error, NULL_TREE); + parm_type = type_decays_to (parm_type); if (!same_type_p (TREE_TYPE (decl_parm), parm_type)) TREE_TYPE (decl_parm) = parm_type; + attributes = DECL_ATTRIBUTES (pattern_parm); + if (DECL_ATTRIBUTES (decl_parm) != attributes) + { + 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); } @@ -11449,6 +11513,7 @@ instantiate_pending_templates (int retries) tree last = NULL_TREE; int reconsider; location_t saved_loc = input_location; + int saved_in_system_header = in_system_header; /* Instantiating templates may trigger vtable generation. This in turn may require further template instantiations. We place a limit here @@ -11533,6 +11598,7 @@ instantiate_pending_templates (int retries) while (reconsider); input_location = saved_loc; + in_system_header = saved_in_system_header; } /* Substitute ARGVEC into T, which is a list of initializers for @@ -12006,6 +12072,7 @@ value_dependent_expression_p (tree expression) { switch (TREE_CODE_CLASS (TREE_CODE (expression))) { + case tcc_reference: case tcc_unary: return (value_dependent_expression_p (TREE_OPERAND (expression, 0))); @@ -12029,7 +12096,6 @@ value_dependent_expression_p (tree expression) return true; return false; } - case tcc_reference: case tcc_statement: /* These cannot be value dependent. */ return false; @@ -12349,7 +12415,8 @@ build_non_dependent_expr (tree expr) if (TREE_CODE (inner_expr) == OVERLOAD || TREE_CODE (inner_expr) == FUNCTION_DECL || TREE_CODE (inner_expr) == TEMPLATE_DECL - || TREE_CODE (inner_expr) == TEMPLATE_ID_EXPR) + || TREE_CODE (inner_expr) == TEMPLATE_ID_EXPR + || TREE_CODE (inner_expr) == OFFSET_REF) return expr; /* There is no need to return a proxy for a variable. */ if (TREE_CODE (expr) == VAR_DECL) |