summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/cp/pt.c
diff options
context:
space:
mode:
authorkan <kan@FreeBSD.org>2003-08-22 02:56:07 +0000
committerkan <kan@FreeBSD.org>2003-08-22 02:56:07 +0000
commit08db0e4d745472adc9c30de407304713c78e950e (patch)
treeaa86de970d24a76b30b53157cf41e9d09ffe4d51 /contrib/gcc/cp/pt.c
parent7b704871fdac058719f34a1e6b9de71ee76c5be4 (diff)
downloadFreeBSD-src-08db0e4d745472adc9c30de407304713c78e950e.zip
FreeBSD-src-08db0e4d745472adc9c30de407304713c78e950e.tar.gz
Gcc 3.3.1-release.
Diffstat (limited to 'contrib/gcc/cp/pt.c')
-rw-r--r--contrib/gcc/cp/pt.c53
1 files changed, 35 insertions, 18 deletions
diff --git a/contrib/gcc/cp/pt.c b/contrib/gcc/cp/pt.c
index 22f93bf..62a66d3 100644
--- a/contrib/gcc/cp/pt.c
+++ b/contrib/gcc/cp/pt.c
@@ -128,7 +128,7 @@ static tree retrieve_specialization PARAMS ((tree, tree));
static tree retrieve_local_specialization PARAMS ((tree));
static tree register_specialization PARAMS ((tree, tree, tree));
static void register_local_specialization PARAMS ((tree, tree));
-static int unregister_specialization PARAMS ((tree, tree));
+static int reregister_specialization PARAMS ((tree, tree, tree));
static tree reduce_template_parm_level PARAMS ((tree, tree, int));
static tree build_template_decl PARAMS ((tree, tree));
static int mark_template_parm PARAMS ((tree, void *));
@@ -1041,13 +1041,11 @@ register_specialization (spec, tmpl, args)
}
/* Unregister the specialization SPEC as a specialization of TMPL.
- Returns nonzero if the SPEC was listed as a specialization of
- TMPL. */
+ Replace it with NEW_SPEC, if NEW_SPEC is non-NULL. Returns true
+ if the SPEC was listed as a specialization of TMPL. */
static int
-unregister_specialization (spec, tmpl)
- tree spec;
- tree tmpl;
+reregister_specialization (tree spec, tree tmpl, tree new_spec)
{
tree* s;
@@ -1056,7 +1054,10 @@ unregister_specialization (spec, tmpl)
s = &TREE_CHAIN (*s))
if (TREE_VALUE (*s) == spec)
{
- *s = TREE_CHAIN (*s);
+ if (!new_spec)
+ *s = TREE_CHAIN (*s);
+ else
+ TREE_VALUE (*s) = new_spec;
return 1;
}
@@ -4086,10 +4087,20 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
}
if (template)
context = DECL_CONTEXT (template);
+ if (template
+ && TREE_CODE (template) == TYPE_DECL
+ && IS_AGGR_TYPE (TREE_TYPE (template))
+ && TREE_CODE (TREE_TYPE (template)) != TEMPLATE_TYPE_PARM)
+ {
+ d1 = template;
+ goto type_decl;
+ }
}
else if (TREE_CODE (d1) == TYPE_DECL && IS_AGGR_TYPE (TREE_TYPE (d1)))
{
- tree type = TREE_TYPE (d1);
+ tree type;
+ type_decl:
+ type = TREE_TYPE (d1);
/* If we are declaring a constructor, say A<T>::A<T>, we will get
an implicit typename for the second A. Deal with it. */
@@ -4997,8 +5008,9 @@ tsubst_friend_function (decl, args)
DECL_TEMPLATE_INFO (old_decl) = new_friend_template_info;
if (TREE_CODE (old_decl) != TEMPLATE_DECL)
- /* duplicate_decls will take care of this case. */
- ;
+ reregister_specialization (new_friend,
+ most_general_template (old_decl),
+ old_decl);
else
{
tree t;
@@ -6340,6 +6352,8 @@ tsubst_decl (t, args, type, complain)
r = copy_decl (t);
if (TREE_CODE (r) == VAR_DECL)
type = complete_type (type);
+ 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);
DECL_CONTEXT (r) = ctx;
@@ -9450,22 +9464,25 @@ more_specialized (pat1, pat2, deduce, len)
1 if PAT1 is more specialized than PAT2 as described in [temp.class.order].
-1 if PAT2 is more specialized than PAT1.
- 0 if neither is more specialized. */
+ 0 if neither is more specialized.
+
+ FULL_ARGS is the full set of template arguments that triggers this
+ partial ordering. */
int
-more_specialized_class (pat1, pat2)
- tree pat1, pat2;
+more_specialized_class (pat1, pat2, full_args)
+ tree pat1, pat2, full_args;
{
tree targs;
int winner = 0;
targs = get_class_bindings (TREE_VALUE (pat1), TREE_PURPOSE (pat1),
- TREE_PURPOSE (pat2));
+ add_outermost_template_args (full_args, TREE_PURPOSE (pat2)));
if (targs)
--winner;
targs = get_class_bindings (TREE_VALUE (pat2), TREE_PURPOSE (pat2),
- TREE_PURPOSE (pat1));
+ add_outermost_template_args (full_args, TREE_PURPOSE (pat1)));
if (targs)
++winner;
@@ -9751,7 +9768,7 @@ most_specialized_class (tmpl, args)
t = TREE_CHAIN (t);
for (; t; t = TREE_CHAIN (t))
{
- fate = more_specialized_class (champ, t);
+ fate = more_specialized_class (champ, t, args);
if (fate == 1)
;
else
@@ -9768,7 +9785,7 @@ most_specialized_class (tmpl, args)
for (t = list; t && t != champ; t = TREE_CHAIN (t))
{
- fate = more_specialized_class (champ, t);
+ fate = more_specialized_class (champ, t, args);
if (fate != 1)
return error_mark_node;
}
@@ -10106,7 +10123,7 @@ regenerate_decl_from_template (decl, tmpl)
instantiation. */
gen_tmpl = most_general_template (tmpl);
push_access_scope_real (gen_tmpl, args, DECL_CONTEXT (decl));
- unregistered = unregister_specialization (decl, gen_tmpl);
+ unregistered = reregister_specialization (decl, gen_tmpl, NULL_TREE);
/* If the DECL was not unregistered then something peculiar is
happening: we created a specialization but did not call
OpenPOWER on IntegriCloud