Commit 8857f91e by Mark Mitchell Committed by Jason Merrill

cp-tree.h (DECL_NONSTATIC_MEMBER_FUNCTION_P): New macro.

	* cp-tree.h (DECL_NONSTATIC_MEMBER_FUNCTION_P): New macro.
	(revert_static_member_fn): Declare.
	* decl.c (revert_static_member_fn): Remove declaration.  Change
	linkage from internal to external.
	(cp_finish_decl): Deal with virtual functions in classes local to
	template functions.
	* decl2.c (finish_file): Don't forget to emit increment/decrement
	expressions in initializers for file-scope variables.
	* parse.y (typename_sub2): If the typename doesn't names a
	template, rather than a type, issue an error message.
	* pt.c (check_explicit_specialization): Handle specializations of
	static member functions.
	(coerce_template_parms): Handle offset references to lists of
	member functions.
	* search.c (note_debug_info_needed): Don't crash when handed a
	type which is being defined.
	* typeck.c (complete_type): Don't crash when handed NULL_TREE;
	that can happen with some illegal code.

From-SVN: r17598
parent 318e3b20
Mon Feb 2 11:24:22 1998 Mark Mitchell <mmitchell@usa.net>
* cp-tree.h (DECL_NONSTATIC_MEMBER_FUNCTION_P): New macro.
(revert_static_member_fn): Declare.
* decl.c (revert_static_member_fn): Remove declaration. Change
linkage from internal to external.
(cp_finish_decl): Deal with virtual functions in classes local to
template functions.
* decl2.c (finish_file): Don't forget to emit increment/decrement
expressions in initializers for file-scope variables.
* parse.y (typename_sub2): If the typename doesn't names a
template, rather than a type, issue an error message.
* pt.c (check_explicit_specialization): Handle specializations of
static member functions.
(coerce_template_parms): Handle offset references to lists of
member functions.
* search.c (note_debug_info_needed): Don't crash when handed a
type which is being defined.
* typeck.c (complete_type): Don't crash when handed NULL_TREE;
that can happen with some illegal code.
Mon Feb 2 00:57:38 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> Mon Feb 2 00:57:38 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* call.c (user_harshness): Initialize `code' to 0. * call.c (user_harshness): Initialize `code' to 0.
......
...@@ -1020,10 +1020,15 @@ struct lang_decl ...@@ -1020,10 +1020,15 @@ struct lang_decl
(TREE_CODE (NODE) == VAR_DECL || TREE_CODE (NODE) == TYPE_DECL \ (TREE_CODE (NODE) == VAR_DECL || TREE_CODE (NODE) == TYPE_DECL \
|| TREE_CODE (NODE) == CONST_DECL) || TREE_CODE (NODE) == CONST_DECL)
/* Nonzero for FUNCTION_DECL means that this decl is a non-static
member function. */
#define DECL_NONSTATIC_MEMBER_FUNCTION_P(NODE) \
(TREE_CODE (TREE_TYPE (NODE)) == METHOD_TYPE)
/* Nonzero for FUNCTION_DECL means that this decl is a member function /* Nonzero for FUNCTION_DECL means that this decl is a member function
(static or non-static). */ (static or non-static). */
#define DECL_FUNCTION_MEMBER_P(NODE) \ #define DECL_FUNCTION_MEMBER_P(NODE) \
(TREE_CODE (TREE_TYPE (NODE)) == METHOD_TYPE || DECL_STATIC_FUNCTION_P (NODE)) (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) || DECL_STATIC_FUNCTION_P (NODE))
/* Nonzero for FUNCTION_DECL means that this member function /* Nonzero for FUNCTION_DECL means that this member function
has `this' as const X *const. */ has `this' as const X *const. */
...@@ -2119,6 +2124,7 @@ extern int in_function_p PROTO((void)); ...@@ -2119,6 +2124,7 @@ extern int in_function_p PROTO((void));
extern void replace_defarg PROTO((tree, tree)); extern void replace_defarg PROTO((tree, tree));
extern void print_other_binding_stack PROTO((struct binding_level *)); extern void print_other_binding_stack PROTO((struct binding_level *));
extern tree strip_attrs PROTO((tree)); extern tree strip_attrs PROTO((tree));
extern void revert_static_member_fn PROTO((tree*, tree*, tree*));
/* in decl2.c */ /* in decl2.c */
extern int flag_assume_nonnull_objects; extern int flag_assume_nonnull_objects;
......
...@@ -136,7 +136,6 @@ static struct stack_level *decl_stack; ...@@ -136,7 +136,6 @@ static struct stack_level *decl_stack;
static tree grokparms PROTO((tree, int)); static tree grokparms PROTO((tree, int));
static tree lookup_nested_type PROTO((tree, tree)); static tree lookup_nested_type PROTO((tree, tree));
static char *redeclaration_error_message PROTO((tree, tree)); static char *redeclaration_error_message PROTO((tree, tree));
static void revert_static_member_fn PROTO((tree *, tree *, tree *));
static tree push_overloaded_decl PROTO((tree, int)); static tree push_overloaded_decl PROTO((tree, int));
static void push_overloaded_decl_top_level PROTO((tree, int)); static void push_overloaded_decl_top_level PROTO((tree, int));
...@@ -6484,8 +6483,10 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags) ...@@ -6484,8 +6483,10 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
{ {
tree stmt = DECL_VINDEX (decl); tree stmt = DECL_VINDEX (decl);
/* If the decl is declaring a member of a local class (in a /* If the decl is declaring a member of a local class (in a
template function), there will be no associated stmt. */ template function), the DECL_VINDEX will either be NULL,
if (stmt != NULL_TREE) or it will be an actual virtual function index, not a
DECL_STMT. */
if (stmt != NULL_TREE && TREE_CODE (stmt) == DECL_STMT)
{ {
DECL_VINDEX (decl) = NULL_TREE; DECL_VINDEX (decl) = NULL_TREE;
TREE_OPERAND (stmt, 2) = copy_to_permanent (init); TREE_OPERAND (stmt, 2) = copy_to_permanent (init);
...@@ -12997,7 +12998,7 @@ finish_stmt () ...@@ -12997,7 +12998,7 @@ finish_stmt ()
(TREE_TYPE (decl)) to ARGTYPES, as doing so will corrupt the types of (TREE_TYPE (decl)) to ARGTYPES, as doing so will corrupt the types of
other decls. Either pass the addresses of local variables or NULL. */ other decls. Either pass the addresses of local variables or NULL. */
static void void
revert_static_member_fn (decl, fn, argtypes) revert_static_member_fn (decl, fn, argtypes)
tree *decl, *fn, *argtypes; tree *decl, *fn, *argtypes;
{ {
......
...@@ -3141,6 +3141,10 @@ finish_file () ...@@ -3141,6 +3141,10 @@ finish_file ()
else else
expand_assignment (decl, init, 0, 0); expand_assignment (decl, init, 0, 0);
/* The expression might have involved increments and
decrements. */
emit_queue ();
/* Cleanup any temporaries needed for the initial value. */ /* Cleanup any temporaries needed for the initial value. */
expand_end_target_temps (); expand_end_target_temps ();
......
...@@ -3309,8 +3309,12 @@ typename_sub2: ...@@ -3309,8 +3309,12 @@ typename_sub2:
TYPENAME SCOPE TYPENAME SCOPE
{ {
if (TREE_CODE ($1) != IDENTIFIER_NODE) if (TREE_CODE ($1) != IDENTIFIER_NODE)
$$ = lastiddecl; $1 = lastiddecl;
got_scope = $$ = complete_type (TREE_TYPE ($$));
got_scope = $$ = complete_type (TREE_TYPE ($1));
if ($$ == error_mark_node)
cp_error ("`%T' is not a class or namespace", $1);
} }
| SELFNAME SCOPE | SELFNAME SCOPE
{ {
......
...@@ -866,6 +866,9 @@ check_explicit_specialization (declarator, decl, template_count, flags) ...@@ -866,6 +866,9 @@ check_explicit_specialization (declarator, decl, template_count, flags)
SET_DECL_EXPLICIT_INSTANTIATION (decl); SET_DECL_EXPLICIT_INSTANTIATION (decl);
return decl; return decl;
} }
else if (DECL_STATIC_FUNCTION_P (tmpl)
&& DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
revert_static_member_fn (&decl, 0, 0);
/* Mangle the function name appropriately. Note that we do /* Mangle the function name appropriately. Note that we do
not mangle specializations of non-template member not mangle specializations of non-template member
...@@ -1822,11 +1825,23 @@ coerce_template_parms (parms, arglist, in_decl, ...@@ -1822,11 +1825,23 @@ coerce_template_parms (parms, arglist, in_decl,
continue; continue;
} }
if (TREE_CODE (arg) == TREE_LIST
&& TREE_TYPE (arg) != NULL_TREE
&& TREE_CODE (TREE_TYPE (arg)) == OFFSET_TYPE)
{
/* The template argument was the name of some
member function. That's usually
illegal, but static members are OK. In any
case, grab the underlying fields/functions
and issue an error later if required. */
arg = TREE_VALUE (arg);
TREE_TYPE (arg) = unknown_type_node;
}
else if (TREE_CODE (arg) == TREE_LIST && ! is_overloaded_fn (arg))
{
/* In case we are checking arguments inside a template template /* In case we are checking arguments inside a template template
parameter, ARG that does not come from default argument is parameter, ARG that does not come from default argument is
also a TREE_LIST node */ also a TREE_LIST node */
if (TREE_CODE (arg) == TREE_LIST && ! is_overloaded_fn (arg))
{
is_tmpl_parm = 1; is_tmpl_parm = 1;
arg = TREE_VALUE (arg); arg = TREE_VALUE (arg);
} }
......
...@@ -3221,6 +3221,10 @@ note_debug_info_needed (type) ...@@ -3221,6 +3221,10 @@ note_debug_info_needed (type)
if (current_template_parms) if (current_template_parms)
return; return;
if (TYPE_BEING_DEFINED (type))
/* We can't go looking for the base types and fields just yet. */
return;
/* We can't do the TYPE_DECL_SUPPRESS_DEBUG thing with DWARF, which /* We can't do the TYPE_DECL_SUPPRESS_DEBUG thing with DWARF, which
does not support name references between translation units. Well, we does not support name references between translation units. Well, we
could, but that would mean putting global labels in the debug output could, but that would mean putting global labels in the debug output
......
...@@ -136,6 +136,11 @@ tree ...@@ -136,6 +136,11 @@ tree
complete_type (type) complete_type (type)
tree type; tree type;
{ {
if (type == NULL_TREE)
/* Rather than crash, we return something sure to cause an error
at some point. */
return error_mark_node;
if (type == error_mark_node || TYPE_SIZE (type) != NULL_TREE) if (type == error_mark_node || TYPE_SIZE (type) != NULL_TREE)
; ;
else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type)) else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
......
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