cp-tree.h (finish_enum): Change prototype.
* cp-tree.h (finish_enum): Change prototype. * decl.c (finish_enum): Use TYPE_VALUES, rather than taking a VALUES parameter. Don't try to compute mins/maxs if processing_template_decl. * parse.y (structsp): Use new calling sequence for finish_enum. * pt.c (tsubst_enum): Likewise. Take the new type as input. (lookup_template_class): Remove unused variables. Tweak. Register enums on instantiation list before substituting enumeration constants. (tsubst_decl): Remove unused variables. (regenerate_decl_from_template): Likewise. * decl.c (duplicate_decls): Don't obliterate the DECL_TEMPLATE_INFO for a template if we're not replacing it with anything. From-SVN: r22004
This commit is contained in:
parent
c0a483c70a
commit
dbfe21241f
@ -1,5 +1,21 @@
|
||||
1998-08-26 Mark Mitchell <mark@markmitchell.com>
|
||||
|
||||
* cp-tree.h (finish_enum): Change prototype.
|
||||
* decl.c (finish_enum): Use TYPE_VALUES, rather than taking a
|
||||
VALUES parameter. Don't try to compute mins/maxs if
|
||||
processing_template_decl.
|
||||
* parse.y (structsp): Use new calling sequence for finish_enum.
|
||||
* pt.c (tsubst_enum): Likewise. Take the new type as input.
|
||||
(lookup_template_class): Remove unused variables. Tweak.
|
||||
Register enums on instantiation list before substituting
|
||||
enumeration constants.
|
||||
(tsubst_decl): Remove unused variables.
|
||||
(regenerate_decl_from_template): Likewise.
|
||||
|
||||
* decl.c (duplicate_decls): Don't obliterate the
|
||||
DECL_TEMPLATE_INFO for a template if we're not replacing it with
|
||||
anything.
|
||||
|
||||
* lex.c (do_identifier): Fix typo in comment.
|
||||
|
||||
Wed Aug 26 10:54:51 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
@ -2562,7 +2562,7 @@ extern tree xref_tag PROTO((tree, tree, tree, int));
|
||||
extern tree xref_tag_from_type PROTO((tree, tree, int));
|
||||
extern void xref_basetypes PROTO((tree, tree, tree, tree));
|
||||
extern tree start_enum PROTO((tree));
|
||||
extern tree finish_enum PROTO((tree, tree));
|
||||
extern tree finish_enum PROTO((tree));
|
||||
extern tree build_enumerator PROTO((tree, tree));
|
||||
extern tree grok_enum_decls PROTO((tree));
|
||||
extern int start_function PROTO((tree, tree, tree, int));
|
||||
|
@ -2982,7 +2982,8 @@ duplicate_decls (newdecl, olddecl)
|
||||
cp_error ("invalid redeclaration of %D", newdecl);
|
||||
TREE_TYPE (olddecl) = TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl));
|
||||
DECL_TEMPLATE_PARMS (olddecl) = DECL_TEMPLATE_PARMS (newdecl);
|
||||
DECL_TEMPLATE_INFO (olddecl) = DECL_TEMPLATE_INFO (newdecl);
|
||||
if (DECL_TEMPLATE_INFO (newdecl))
|
||||
DECL_TEMPLATE_INFO (olddecl) = DECL_TEMPLATE_INFO (newdecl);
|
||||
DECL_TEMPLATE_SPECIALIZATIONS (olddecl)
|
||||
= chainon (DECL_TEMPLATE_SPECIALIZATIONS (olddecl),
|
||||
DECL_TEMPLATE_SPECIALIZATIONS (newdecl));
|
||||
@ -11861,12 +11862,13 @@ start_enum (name)
|
||||
Returns ENUMTYPE. */
|
||||
|
||||
tree
|
||||
finish_enum (enumtype, values)
|
||||
register tree enumtype, values;
|
||||
finish_enum (enumtype)
|
||||
tree enumtype;
|
||||
{
|
||||
register tree minnode = NULL_TREE, maxnode = NULL_TREE;
|
||||
/* Calculate the maximum value of any enumerator in this type. */
|
||||
|
||||
tree values = TYPE_VALUES (enumtype);
|
||||
if (values)
|
||||
{
|
||||
tree pair;
|
||||
@ -11899,12 +11901,15 @@ finish_enum (enumtype, values)
|
||||
= build1 (NOP_EXPR, enumtype, value);
|
||||
TREE_TYPE (value) = enumtype;
|
||||
|
||||
if (!minnode)
|
||||
minnode = maxnode = value;
|
||||
else if (tree_int_cst_lt (maxnode, value))
|
||||
maxnode = value;
|
||||
else if (tree_int_cst_lt (value, minnode))
|
||||
minnode = value;
|
||||
if (!processing_template_decl)
|
||||
{
|
||||
if (!minnode)
|
||||
minnode = maxnode = value;
|
||||
else if (tree_int_cst_lt (maxnode, value))
|
||||
maxnode = value;
|
||||
else if (tree_int_cst_lt (value, minnode))
|
||||
minnode = value;
|
||||
}
|
||||
}
|
||||
|
||||
/* In the list we're building up, we want the enumeration
|
||||
|
@ -2060,24 +2060,26 @@ structsp:
|
||||
{ $<itype>3 = suspend_momentary ();
|
||||
$<ttype>$ = start_enum ($2); }
|
||||
enumlist maybecomma_warn '}'
|
||||
{ $$.t = finish_enum ($<ttype>4, $5);
|
||||
{ TYPE_VALUES ($<ttype>4) = $5;
|
||||
$$.t = finish_enum ($<ttype>4);
|
||||
$$.new_type_flag = 1;
|
||||
resume_momentary ((int) $<itype>3);
|
||||
check_for_missing_semicolon ($<ttype>4); }
|
||||
| ENUM identifier '{' '}'
|
||||
{ $$.t = finish_enum (start_enum ($2), NULL_TREE);
|
||||
{ $$.t = finish_enum (start_enum ($2));
|
||||
$$.new_type_flag = 1;
|
||||
check_for_missing_semicolon ($$.t); }
|
||||
| ENUM '{'
|
||||
{ $<itype>2 = suspend_momentary ();
|
||||
$<ttype>$ = start_enum (make_anon_name ()); }
|
||||
enumlist maybecomma_warn '}'
|
||||
{ $$.t = finish_enum ($<ttype>3, $4);
|
||||
{ TYPE_VALUES ($<ttype>3) = $4;
|
||||
$$.t = finish_enum ($<ttype>3);
|
||||
resume_momentary ((int) $<itype>1);
|
||||
check_for_missing_semicolon ($<ttype>3);
|
||||
$$.new_type_flag = 1; }
|
||||
| ENUM '{' '}'
|
||||
{ $$.t = finish_enum (start_enum (make_anon_name()), NULL_TREE);
|
||||
{ $$.t = finish_enum (start_enum (make_anon_name()));
|
||||
$$.new_type_flag = 1;
|
||||
check_for_missing_semicolon ($$.t); }
|
||||
| ENUM identifier
|
||||
|
88
gcc/cp/pt.c
88
gcc/cp/pt.c
@ -85,7 +85,7 @@ static tree tsubst_expr_values PROTO((tree, tree));
|
||||
static int list_eq PROTO((tree, tree));
|
||||
static tree get_class_bindings PROTO((tree, tree, tree));
|
||||
static tree coerce_template_parms PROTO((tree, tree, tree, int, int));
|
||||
static tree tsubst_enum PROTO((tree, tree));
|
||||
static void tsubst_enum PROTO((tree, tree, tree));
|
||||
static tree add_to_template_args PROTO((tree, tree));
|
||||
static tree add_outermost_template_args PROTO((tree, tree));
|
||||
static void maybe_adjust_types_for_deduction PROTO((unification_kind_t, tree*,
|
||||
@ -3152,8 +3152,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
|
||||
int entering_scope;
|
||||
{
|
||||
tree template = NULL_TREE, parmlist;
|
||||
char *mangled_name;
|
||||
tree id, t;
|
||||
tree t;
|
||||
|
||||
if (TREE_CODE (d1) == IDENTIFIER_NODE)
|
||||
{
|
||||
@ -3242,11 +3241,14 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
|
||||
}
|
||||
else
|
||||
{
|
||||
extern tree current_local_enum;
|
||||
tree template_type = TREE_TYPE (template);
|
||||
tree type_decl;
|
||||
tree found = NULL_TREE;
|
||||
int arg_depth;
|
||||
int parm_depth;
|
||||
int is_partial_instantiation;
|
||||
tree prev_local_enum;
|
||||
|
||||
template = most_general_template (template);
|
||||
parmlist = DECL_TEMPLATE_PARMS (template);
|
||||
@ -3398,13 +3400,20 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
|
||||
DECL_TEMPLATE_INSTANTIATIONS list, it must be permanent. */
|
||||
push_obstacks (&permanent_obstack, &permanent_obstack);
|
||||
|
||||
/* This type is a "partial instantiation" if any of the template
|
||||
arguments still inolve template parameters. */
|
||||
is_partial_instantiation = uses_template_parms (arglist);
|
||||
|
||||
/* Create the type. */
|
||||
if (TREE_CODE (template_type) == ENUMERAL_TYPE)
|
||||
{
|
||||
if (!uses_template_parms (arglist))
|
||||
t = tsubst_enum (template_type, arglist);
|
||||
if (!is_partial_instantiation)
|
||||
{
|
||||
prev_local_enum = current_local_enum;
|
||||
t = start_enum (TYPE_IDENTIFIER (template_type));
|
||||
}
|
||||
else
|
||||
/* We don't want to call tsubst_enum for this type, since
|
||||
/* We don't want to call start_enum for this type, since
|
||||
the values for the enumeration constants may involve
|
||||
template parameters. And, no one should be interested
|
||||
in the enumeration constants for such a type. */
|
||||
@ -3439,22 +3448,37 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
|
||||
else
|
||||
type_decl = TYPE_NAME (t);
|
||||
|
||||
/* We're done with the permanent obstack, now. */
|
||||
pop_obstacks ();
|
||||
|
||||
/* Set up the template information. */
|
||||
arglist = copy_to_permanent (arglist);
|
||||
SET_TYPE_TEMPLATE_INFO (t,
|
||||
perm_tree_cons (template, arglist, NULL_TREE));
|
||||
DECL_TEMPLATE_INSTANTIATIONS (template) = perm_tree_cons
|
||||
(arglist, t, DECL_TEMPLATE_INSTANTIATIONS (template));
|
||||
tree_cons (template, arglist, NULL_TREE));
|
||||
DECL_TEMPLATE_INSTANTIATIONS (template)
|
||||
= tree_cons (arglist, t,
|
||||
DECL_TEMPLATE_INSTANTIATIONS (template));
|
||||
|
||||
if (TREE_CODE (t) == ENUMERAL_TYPE
|
||||
&& !is_partial_instantiation)
|
||||
{
|
||||
/* Now that the type has been registered on the
|
||||
instantiations list, we set up the enumerators. Because
|
||||
the enumeration constants may involve the enumeration
|
||||
type itself, we make sure to register the type first, and
|
||||
then create the constants. That way, doing tsubst_expr
|
||||
for the enumeration constants won't result in recursive
|
||||
calls here; we'll find the instantiation and exit above. */
|
||||
tsubst_enum (template_type, t, arglist);
|
||||
current_local_enum = prev_local_enum;
|
||||
}
|
||||
|
||||
/* We're done with the permanent obstack, now. */
|
||||
pop_obstacks ();
|
||||
|
||||
/* Reset the name of the type, now that CLASSTYPE_TEMPLATE_INFO
|
||||
is set up. */
|
||||
if (TREE_CODE (t) != ENUMERAL_TYPE)
|
||||
DECL_NAME (type_decl) = classtype_mangled_name (t);
|
||||
DECL_ASSEMBLER_NAME (type_decl) = DECL_NAME (type_decl);
|
||||
if (! uses_template_parms (arglist))
|
||||
if (!is_partial_instantiation)
|
||||
{
|
||||
DECL_ASSEMBLER_NAME (type_decl)
|
||||
= get_identifier (build_overload_name (t, 1, 1));
|
||||
@ -4708,8 +4732,6 @@ tsubst_decl (t, args, type, in_decl)
|
||||
/* We can get here when processing a member template function
|
||||
of a template class. */
|
||||
tree decl = DECL_TEMPLATE_RESULT (t);
|
||||
tree parms;
|
||||
tree* new_parms;
|
||||
tree spec;
|
||||
int is_template_template_parm = DECL_TEMPLATE_TEMPLATE_PARM_P (t);
|
||||
|
||||
@ -7781,7 +7803,6 @@ regenerate_decl_from_template (decl, tmpl)
|
||||
tree tmpl;
|
||||
{
|
||||
tree args;
|
||||
tree save_ti;
|
||||
tree code_pattern;
|
||||
tree new_decl;
|
||||
tree gen_tmpl;
|
||||
@ -8172,17 +8193,17 @@ add_maybe_template (d, fns)
|
||||
DECL_MAYBE_TEMPLATE (d) = 1;
|
||||
}
|
||||
|
||||
/* Instantiate an enumerated type. */
|
||||
/* Instantiate an enumerated type. TAG is the template type, NEWTAG
|
||||
is the instantiation (which should have been created with
|
||||
start_enum) and ARGS are the template arguments to use. */
|
||||
|
||||
static tree
|
||||
tsubst_enum (tag, args)
|
||||
tree tag, args;
|
||||
static void
|
||||
tsubst_enum (tag, newtag, args)
|
||||
tree tag;
|
||||
tree newtag;
|
||||
tree args;
|
||||
{
|
||||
extern tree current_local_enum;
|
||||
tree prev_local_enum = current_local_enum;
|
||||
|
||||
tree newtag = start_enum (TYPE_IDENTIFIER (tag));
|
||||
tree e, values = NULL_TREE;
|
||||
tree e;
|
||||
|
||||
for (e = TYPE_VALUES (tag); e; e = TREE_CHAIN (e))
|
||||
{
|
||||
@ -8194,21 +8215,22 @@ tsubst_enum (tag, args)
|
||||
{
|
||||
if (TREE_CODE (value) == NOP_EXPR)
|
||||
/* This is the special case where the value is really a
|
||||
TEMPLATE_PARM_INDEX. See finish_enum. */
|
||||
TEMPLATE_PARM_INDEX. See finish_enum. */
|
||||
value = TREE_OPERAND (value, 0);
|
||||
value = tsubst_expr (value, args, NULL_TREE);
|
||||
}
|
||||
|
||||
elt = build_enumerator (TREE_PURPOSE (e), value);
|
||||
TREE_CHAIN (elt) = values;
|
||||
values = elt;
|
||||
|
||||
/* We save the enumerators we have built so far in the
|
||||
TYPE_VALUES so that if the enumeration constants for
|
||||
subsequent enumerators involve those for previous ones,
|
||||
tsubst_copy will be able to find them. */
|
||||
TREE_CHAIN (elt) = TYPE_VALUES (newtag);
|
||||
TYPE_VALUES (newtag) = elt;
|
||||
}
|
||||
|
||||
finish_enum (newtag, values);
|
||||
|
||||
current_local_enum = prev_local_enum;
|
||||
|
||||
return newtag;
|
||||
finish_enum (newtag);
|
||||
}
|
||||
|
||||
/* Set the DECL_ASSEMBLER_NAME for DECL, which is a FUNCTION_DECL that
|
||||
|
18
gcc/testsuite/g++.old-deja/g++.pt/enum8.C
Normal file
18
gcc/testsuite/g++.old-deja/g++.pt/enum8.C
Normal file
@ -0,0 +1,18 @@
|
||||
// Build don't link:
|
||||
|
||||
template <int I>
|
||||
void f();
|
||||
|
||||
template <>
|
||||
void f<4>() {}
|
||||
|
||||
template <class T>
|
||||
struct S
|
||||
{
|
||||
enum E { a = 1, b = a + 3 };
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
f<S<int>::b>();
|
||||
}
|
Loading…
Reference in New Issue
Block a user