aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/pt.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r--gcc/cp/pt.c122
1 files changed, 101 insertions, 21 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 7025deff788..ad4e87aaafe 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 Objective-C++ */
+#include "c-common.h"
#include "cp-tree.h"
+/* APPLE LOCAL Objective-C++ */
+#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);
@@ -4012,7 +4024,26 @@ template_args_equal (tree ot, tree nt)
/* For member templates */
return TREE_CODE (ot) == TREE_VEC && comp_template_args (ot, nt);
else if (TYPE_P (nt))
- return TYPE_P (ot) && same_type_p (ot, nt);
+ /* APPLE LOCAL begin Objective-C++ */
+ {
+ int c1, c2;
+
+ if (!TYPE_P (ot))
+ return 0;
+
+ /* We must handle ObjC types specially because they may differ
+ only in protocol qualifications (e.g., 'NSObject *' vs.
+ 'NSObject <Foo> *') that must be taken into account here.
+ See also cp/typeck.c:build_c_cast(), where a similar problem
+ arises. We must call objc_comptypes() twice, since its
+ comparisons are _not_ symmetric. */
+ if ((c1 = objc_comptypes (ot, nt, 0)) >= 0
+ && (c2 = objc_comptypes (nt, ot, 0)) >= 0)
+ return (c1 && c2);
+
+ return same_type_p (ot, nt);
+ }
+ /* APPLE LOCAL end Objective-C++ */
else if (TREE_CODE (ot) == TREE_VEC || TYPE_P (ot))
return 0;
else
@@ -6468,8 +6499,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 +6531,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 +6631,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 +7250,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 +8867,18 @@ tsubst_copy_and_build (tree t,
return t;
default:
+ /* APPLE LOCAL begin Objective-C++ */
+ /* 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 Objective-C++ */
+
return tsubst_copy (t, args, complain, in_decl);
}
@@ -10251,6 +10291,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 +11128,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);
}
@@ -12006,6 +12085,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 +12109,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 +12428,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)