semantics.c (finish_stmt_expr): Fix typo in comment.

* semantics.c (finish_stmt_expr): Fix typo in comment.
	* tree.c (search_tree): Handle EXIT_EXPR, LOOP_EXPR.
	(mapcar): Likewise.
	* init.c (build_vec_delete_1): Make the children of a permanent
	BIND_EXPR permanent.
	* pt.c (register_specialization): Don't register a specialization
	more than once.

From-SVN: r28781
This commit is contained in:
Mark Mitchell 1999-08-20 22:07:22 +00:00 committed by Mark Mitchell
parent b61148dd4f
commit 22e9174f54
6 changed files with 117 additions and 48 deletions

View File

@ -1,3 +1,13 @@
1999-08-20 Mark Mitchell <mark@codesourcery.com>
* semantics.c (finish_stmt_expr): Fix typo in comment.
* tree.c (search_tree): Handle EXIT_EXPR, LOOP_EXPR.
(mapcar): Likewise.
* init.c (build_vec_delete_1): Make the children of a permanent
BIND_EXPR permanent.
* pt.c (register_specialization): Don't register a specialization
more than once.
1999-08-18 Andrew Haley <aph@cygnus.com>
* method.c (process_overload_item): Call build_mangled_C9x_name ()

View File

@ -2673,6 +2673,15 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, auto_delete,
if (controller)
{
/* The CONTROLLER is a BIND_EXPR. Such things are always
allocated on at least the saveable obstack. Since we may
need to copy this expression to the permanent obstack, we
must make sure that the operand is on the same obstack as the
BIND_EXPR. Otherwise, copy_to_permanent will not copy the
operand, since it will assume that anything under a permanent
node is permanent. */
if (TREE_PERMANENT (controller))
body = copy_to_permanent (body);
TREE_OPERAND (controller, 1) = body;
return controller;
}

View File

@ -842,59 +842,68 @@ register_specialization (spec, tmpl, args)
for (s = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
s != NULL_TREE;
s = TREE_CHAIN (s))
if (comp_template_args (TREE_PURPOSE (s), args))
{
tree fn = TREE_VALUE (s);
{
tree fn = TREE_VALUE (s);
if (DECL_TEMPLATE_SPECIALIZATION (spec))
{
if (DECL_TEMPLATE_INSTANTIATION (fn))
{
if (TREE_USED (fn)
|| DECL_EXPLICIT_INSTANTIATION (fn))
{
cp_error ("specialization of %D after instantiation",
fn);
return spec;
}
else
{
/* This situation should occur only if the first
specialization is an implicit instantiation,
the second is an explicit specialization, and
the implicit instantiation has not yet been
used. That situation can occur if we have
implicitly instantiated a member function and
then specialized it later.
/* We can sometimes try to re-register a specialization that we've
already got. In particular, regenerate_decl_from_template
calls duplicate_decls which will update the specialization
list. But, we'll still get called again here anyhow. It's
more convenient to simply allow this than to try to prevent it. */
if (fn == spec)
return spec;
else if (comp_template_args (TREE_PURPOSE (s), args))
{
if (DECL_TEMPLATE_SPECIALIZATION (spec))
{
if (DECL_TEMPLATE_INSTANTIATION (fn))
{
if (TREE_USED (fn)
|| DECL_EXPLICIT_INSTANTIATION (fn))
{
cp_error ("specialization of %D after instantiation",
fn);
return spec;
}
else
{
/* This situation should occur only if the first
specialization is an implicit instantiation,
the second is an explicit specialization, and
the implicit instantiation has not yet been
used. That situation can occur if we have
implicitly instantiated a member function and
then specialized it later.
We can also wind up here if a friend
declaration that looked like an instantiation
turns out to be a specialization:
We can also wind up here if a friend
declaration that looked like an instantiation
turns out to be a specialization:
template <class T> void foo(T);
class S { friend void foo<>(int) };
template <> void foo(int);
template <class T> void foo(T);
class S { friend void foo<>(int) };
template <> void foo(int);
We transform the existing DECL in place so that
any pointers to it become pointers to the
updated declaration.
We transform the existing DECL in place so that
any pointers to it become pointers to the
updated declaration.
If there was a definition for the template, but
not for the specialization, we want this to
look as if there is no definition, and vice
versa. */
DECL_INITIAL (fn) = NULL_TREE;
duplicate_decls (spec, fn);
If there was a definition for the template, but
not for the specialization, we want this to
look as if there is no definition, and vice
versa. */
DECL_INITIAL (fn) = NULL_TREE;
duplicate_decls (spec, fn);
return fn;
}
}
else if (DECL_TEMPLATE_SPECIALIZATION (fn))
{
duplicate_decls (spec, fn);
return fn;
}
}
return fn;
}
}
else if (DECL_TEMPLATE_SPECIALIZATION (fn))
{
duplicate_decls (spec, fn);
return fn;
}
}
}
}
DECL_TEMPLATE_SPECIALIZATIONS (tmpl)

View File

@ -1057,7 +1057,7 @@ finish_stmt_expr (rtl_expr, expr)
if (TREE_CODE (expr) == BLOCK)
{
/* Make a CP_BIND_EXPR for the BLOCK already made. */
/* Make a BIND_EXPR for the BLOCK already made. */
if (building_stmt_tree ())
{
result = build_min (STMT_EXPR, last_expr_type, last_tree);

View File

@ -1668,6 +1668,8 @@ search_tree (t, func)
case CLEANUP_POINT_EXPR:
case LOOKUP_EXPR:
case THROW_EXPR:
case EXIT_EXPR:
case LOOP_EXPR:
TRY (TREE_OPERAND (t, 0));
break;
@ -2001,6 +2003,8 @@ mapcar (t, func)
return t;
case LOOKUP_EXPR:
case EXIT_EXPR:
case LOOP_EXPR:
t = copy_node (t);
TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
return t;

View File

@ -0,0 +1,37 @@
// Build don't link:
// Origin: Loring Holden <lsh@cs.brown.edu>
template <class T>
class REFptr {
public:
virtual ~REFptr();
REFptr<T> &operator = (const REFptr<T>& p);
};
class STR { };
class str_ptr : public REFptr<STR> { };
template <class T>
class ARRAY {
protected:
T *_array;
int _num;
int _max;
public:
virtual void realloc(int new_max) {
_max = new_max;
T *tmp = new T [_max];
if (tmp == 0) return;
for (int i=0; i<_num; i++) {
tmp[i] = _array[i];
}
delete [] _array;
_array = tmp;
}
};
int
main()
{
ARRAY<str_ptr> tags;
}