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.c133
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)