Commit 22e9174f by Mark Mitchell Committed by Mark Mitchell

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
parent b61148dd
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> 1999-08-18 Andrew Haley <aph@cygnus.com>
* method.c (process_overload_item): Call build_mangled_C9x_name () * method.c (process_overload_item): Call build_mangled_C9x_name ()
......
...@@ -2673,6 +2673,15 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, auto_delete, ...@@ -2673,6 +2673,15 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, auto_delete,
if (controller) 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; TREE_OPERAND (controller, 1) = body;
return controller; return controller;
} }
......
...@@ -842,59 +842,68 @@ register_specialization (spec, tmpl, args) ...@@ -842,59 +842,68 @@ register_specialization (spec, tmpl, args)
for (s = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); for (s = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
s != NULL_TREE; s != NULL_TREE;
s = TREE_CHAIN (s)) 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)) /* We can sometimes try to re-register a specialization that we've
{ already got. In particular, regenerate_decl_from_template
if (DECL_TEMPLATE_INSTANTIATION (fn)) calls duplicate_decls which will update the specialization
{ list. But, we'll still get called again here anyhow. It's
if (TREE_USED (fn) more convenient to simply allow this than to try to prevent it. */
|| DECL_EXPLICIT_INSTANTIATION (fn)) if (fn == spec)
{ return spec;
cp_error ("specialization of %D after instantiation", else if (comp_template_args (TREE_PURPOSE (s), args))
fn); {
return spec; if (DECL_TEMPLATE_SPECIALIZATION (spec))
} {
else if (DECL_TEMPLATE_INSTANTIATION (fn))
{ {
/* This situation should occur only if the first if (TREE_USED (fn)
specialization is an implicit instantiation, || DECL_EXPLICIT_INSTANTIATION (fn))
the second is an explicit specialization, and {
the implicit instantiation has not yet been cp_error ("specialization of %D after instantiation",
used. That situation can occur if we have fn);
implicitly instantiated a member function and return spec;
then specialized it later. }
else
We can also wind up here if a friend {
declaration that looked like an instantiation /* This situation should occur only if the first
turns out to be a specialization: specialization is an implicit instantiation,
the second is an explicit specialization, and
template <class T> void foo(T); the implicit instantiation has not yet been
class S { friend void foo<>(int) }; used. That situation can occur if we have
template <> void foo(int); implicitly instantiated a member function and
then specialized it later.
We transform the existing DECL in place so that
any pointers to it become pointers to the We can also wind up here if a friend
updated declaration. declaration that looked like an instantiation
turns out to be a specialization:
If there was a definition for the template, but
not for the specialization, we want this to template <class T> void foo(T);
look as if there is no definition, and vice class S { friend void foo<>(int) };
versa. */ template <> void foo(int);
DECL_INITIAL (fn) = NULL_TREE;
duplicate_decls (spec, fn); We transform the existing DECL in place so that
any pointers to it become pointers to the
return fn; updated declaration.
}
} If there was a definition for the template, but
else if (DECL_TEMPLATE_SPECIALIZATION (fn)) not for the specialization, we want this to
{ look as if there is no definition, and vice
duplicate_decls (spec, fn); versa. */
return fn; DECL_INITIAL (fn) = NULL_TREE;
} duplicate_decls (spec, fn);
}
return fn;
}
}
else if (DECL_TEMPLATE_SPECIALIZATION (fn))
{
duplicate_decls (spec, fn);
return fn;
}
}
}
} }
DECL_TEMPLATE_SPECIALIZATIONS (tmpl) DECL_TEMPLATE_SPECIALIZATIONS (tmpl)
......
...@@ -1057,7 +1057,7 @@ finish_stmt_expr (rtl_expr, expr) ...@@ -1057,7 +1057,7 @@ finish_stmt_expr (rtl_expr, expr)
if (TREE_CODE (expr) == BLOCK) 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 ()) if (building_stmt_tree ())
{ {
result = build_min (STMT_EXPR, last_expr_type, last_tree); result = build_min (STMT_EXPR, last_expr_type, last_tree);
......
...@@ -1668,6 +1668,8 @@ search_tree (t, func) ...@@ -1668,6 +1668,8 @@ search_tree (t, func)
case CLEANUP_POINT_EXPR: case CLEANUP_POINT_EXPR:
case LOOKUP_EXPR: case LOOKUP_EXPR:
case THROW_EXPR: case THROW_EXPR:
case EXIT_EXPR:
case LOOP_EXPR:
TRY (TREE_OPERAND (t, 0)); TRY (TREE_OPERAND (t, 0));
break; break;
...@@ -2001,6 +2003,8 @@ mapcar (t, func) ...@@ -2001,6 +2003,8 @@ mapcar (t, func)
return t; return t;
case LOOKUP_EXPR: case LOOKUP_EXPR:
case EXIT_EXPR:
case LOOP_EXPR:
t = copy_node (t); t = copy_node (t);
TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func); TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
return t; return t;
......
// 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment