Commit f181d4ae by Mark Mitchell Committed by Mark Mitchell

cp-tree.def (CPLUS_BINDING): Update documentation.

	* cp-tree.def (CPLUS_BINDING): Update documentation.
	* cp-tree.h (LOCAL_BINDING_P): New macro.
	(lang_identifier): Rename local_value to bindings.
	(tree_binding): Make `scope' of type `void*', not `tree'.
	(BINDING_SCOPE): Update documentation.
	(IDENTIFIER_LOCAL_VALUE): Remove.
	(IDENTIFIER_CLASS_VALUE): Document.
	(IDENTIFIER_BINDING): New macro.
	(IDENTIFIER_VALUE): Likewise.
	(TIME_IDENTIFIER_TIME): Likewise.
	(TIME_IDENTIFIER_FILEINFO): Likewise.
	(IMPLICIT_TYPENAME_P): Likewise.
	(set_identifier_local_value): Remove.
	(push_local_binding): New function.
	(push_class_binding): Likewise.
	* class.c (pushclass): Update comments; use push_class_binding.
	* decl.c (set_identifier_local_value_with_scope): Remove.
	(set_identifier_local_value): Likewise.
	(push_binding): New function.
	(pop_binding): Likewise.
	(binding_level): Update documentation.  Remove shadowed.
	(BINDING_LEVEL): New macro.
	(free_binding_nodes): New variable.
	(poplevel): Adjust for new name-lookup scheme.  Don't mess up
	BLOCK_VARs when doing for-scope extension.  Remove effectively
	dead code.
	(pushlevel_class): Tweak formatting.
	(poplevel_class): Adjust for new name-lookup scheme.
	(print_binding_level): Likewise.
	(store_bindings): Likewise.
	(pushdecl): Likewise.
	(pushdecl_class_level): Likewise.
	(push_class_level_binding): Likewise.
	(push_overloaded_decl): Update comments.  Adjust for new
	name-lookup scheme.
	(lookup_name_real): Likewise.
	(lookup_name_current_level): Likewise.
	(cp_finish_decl): Likewise.
	(require_complete_types_for_parms): Likewise.  Remove misleading
	#if 0'd code.
	(grok_parms): Likewise.  Don't call
	require_complete_types_for_parms here.
	(grok_ctor_properties): Don't treat templates as copy
	constructors.
	(grop_op_properties): Or as assignment operators.
	(start_function): Document.  Adjust for new name-lookup scheme.
	(finish_function): Likewise.
	* decl2.c (do_local_using_decl): Use push_local_binding.
	* lex.c (begin_definition_of_inclass_inline): New function, split
	out from ...
	(do_pending_inlines): Here, and ...
	(process_next_inline): Here.
	(get_time_identifier): Use TIME_IDENTIFIER_* macros.
	(init_filename_times): Likewise.
	(extract_interface_info): Likewise.
	(ste_typedecl_interface_info): Likewise.
	(check_newline): Likewise.
	(dump_time_statistics): Likewise.
	(handle_cp_pragma): Likewise.
	(do_identifier): Adjust for new name-lookup scheme.
	* parse.y (function_try_block): Return ctor_initializer_opt value.
	(fndef): Use it.
	(fn.defpen): Pass appropriate values to start_function.
	(pending_inline): Use functor_try_block value, and pass
	appropriate values to finish_function.
	* pt.c (is_member_template): Update documentation; remove handling
	of FUNCTION_DECLs.  As per name, this function should deal only in
	TEMPLATE_DECLs.
	(decl_template_parm_p): Change name of olddecl parameter to decl.
	(check_template_shadow): Adjust for new name-lookup scheme.
	(lookup_template_class): Likewise.
	(tsubst_decl): Tweak so as not to confuse member templates with
	copy constructors and assignment operators.
	(unify): Handle UNION_TYPEs.
	* ptree.c (print_lang_identifier): Adjust for new name-lookup scheme.
	(lang_print_xnode): Adjust for new name-lookup scheme.
	* typeck.c (mark_addressable): Likewise.
	(c_expand_return): Likewise.

From-SVN: r24296
parent 92c068d1
1998-12-13 Mark Mitchell <mark@markmitchell.com>
* cp-tree.def (CPLUS_BINDING): Update documentation.
* cp-tree.h (LOCAL_BINDING_P): New macro.
(lang_identifier): Rename local_value to bindings.
(tree_binding): Make `scope' of type `void*', not `tree'.
(BINDING_SCOPE): Update documentation.
(IDENTIFIER_LOCAL_VALUE): Remove.
(IDENTIFIER_CLASS_VALUE): Document.
(IDENTIFIER_BINDING): New macro.
(IDENTIFIER_VALUE): Likewise.
(TIME_IDENTIFIER_TIME): Likewise.
(TIME_IDENTIFIER_FILEINFO): Likewise.
(IMPLICIT_TYPENAME_P): Likewise.
(set_identifier_local_value): Remove.
(push_local_binding): New function.
(push_class_binding): Likewise.
* class.c (pushclass): Update comments; use push_class_binding.
* decl.c (set_identifier_local_value_with_scope): Remove.
(set_identifier_local_value): Likewise.
(push_binding): New function.
(pop_binding): Likewise.
(binding_level): Update documentation. Remove shadowed.
(BINDING_LEVEL): New macro.
(free_binding_nodes): New variable.
(poplevel): Adjust for new name-lookup scheme. Don't mess up
BLOCK_VARs when doing for-scope extension. Remove effectively
dead code.
(pushlevel_class): Tweak formatting.
(poplevel_class): Adjust for new name-lookup scheme.
(print_binding_level): Likewise.
(store_bindings): Likewise.
(pushdecl): Likewise.
(pushdecl_class_level): Likewise.
(push_class_level_binding): Likewise.
(push_overloaded_decl): Update comments. Adjust for new
name-lookup scheme.
(lookup_name_real): Likewise.
(lookup_name_current_level): Likewise.
(cp_finish_decl): Likewise.
(require_complete_types_for_parms): Likewise. Remove misleading
#if 0'd code.
(grok_parms): Likewise. Don't call
require_complete_types_for_parms here.
(grok_ctor_properties): Don't treat templates as copy
constructors.
(grop_op_properties): Or as assignment operators.
(start_function): Document. Adjust for new name-lookup scheme.
(finish_function): Likewise.
* decl2.c (do_local_using_decl): Use push_local_binding.
* lex.c (begin_definition_of_inclass_inline): New function, split
out from ...
(do_pending_inlines): Here, and ...
(process_next_inline): Here.
(get_time_identifier): Use TIME_IDENTIFIER_* macros.
(init_filename_times): Likewise.
(extract_interface_info): Likewise.
(ste_typedecl_interface_info): Likewise.
(check_newline): Likewise.
(dump_time_statistics): Likewise.
(handle_cp_pragma): Likewise.
(do_identifier): Adjust for new name-lookup scheme.
* parse.y (function_try_block): Return ctor_initializer_opt value.
(fndef): Use it.
(fn.defpen): Pass appropriate values to start_function.
(pending_inline): Use functor_try_block value, and pass
appropriate values to finish_function.
* pt.c (is_member_template): Update documentation; remove handling
of FUNCTION_DECLs. As per name, this function should deal only in
TEMPLATE_DECLs.
(decl_template_parm_p): Change name of olddecl parameter to decl.
(check_template_shadow): Adjust for new name-lookup scheme.
(lookup_template_class): Likewise.
(tsubst_decl): Tweak so as not to confuse member templates with
copy constructors and assignment operators.
(unify): Handle UNION_TYPEs.
* ptree.c (print_lang_identifier): Adjust for new name-lookup scheme.
(lang_print_xnode): Adjust for new name-lookup scheme.
* typeck.c (mark_addressable): Likewise.
(c_expand_return): Likewise.
1998-12-08 Jason Merrill <jason@yorick.cygnus.com> 1998-12-08 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (grokdeclarator): Allow field with same name as class * decl.c (grokdeclarator): Allow field with same name as class
......
...@@ -4780,15 +4780,18 @@ pushclass (type, modify) ...@@ -4780,15 +4780,18 @@ pushclass (type, modify)
{ {
tree item; tree item;
/* Hooray, we successfully cached; let's just install the /* We are re-entering the same class we just left, so we
cached class_shadowed list, and walk through it to get the don't have to search the whole inheritance matrix to find
IDENTIFIER_TYPE_VALUEs correct. */ all the decls to bind again. Instead, we install the
cached class_shadowed list, and walk through it binding
names and setting up IDENTIFIER_TYPE_VALUEs. */
set_class_shadows (previous_class_values); set_class_shadows (previous_class_values);
for (item = previous_class_values; item; item = TREE_CHAIN (item)) for (item = previous_class_values; item; item = TREE_CHAIN (item))
{ {
tree id = TREE_PURPOSE (item); tree id = TREE_PURPOSE (item);
tree decl = IDENTIFIER_CLASS_VALUE (id); tree decl = IDENTIFIER_CLASS_VALUE (id);
push_class_binding (id, decl);
if (TREE_CODE (decl) == TYPE_DECL) if (TREE_CODE (decl) == TYPE_DECL)
set_identifier_type_value (id, TREE_TYPE (decl)); set_identifier_type_value (id, TREE_TYPE (decl));
} }
......
...@@ -178,9 +178,9 @@ DEFTREECODE (DEFAULT_ARG, "default_arg", 'c', 2) ...@@ -178,9 +178,9 @@ DEFTREECODE (DEFAULT_ARG, "default_arg", 'c', 2)
the template may be an IDENTIFIER_NODE. */ the template may be an IDENTIFIER_NODE. */
DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2) DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2)
/* An association between namespace and entity. Parameters are the /* An association between name and entity. Parameters are the scope
scope and the (non-type) value. and the (non-type) value. TREE_TYPE indicates the type bound to
TREE_TYPE indicates the type bound to the name. */ the name. */
DEFTREECODE (CPLUS_BINDING, "binding", 'x', 2) DEFTREECODE (CPLUS_BINDING, "binding", 'x', 2)
/* A list-like node for chaining overloading candidates. TREE_TYPE is /* A list-like node for chaining overloading candidates. TREE_TYPE is
......
...@@ -31,6 +31,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -31,6 +31,7 @@ Boston, MA 02111-1307, USA. */
LOOKUP_EXPR_GLOBAL (in LOOKUP_EXPR). LOOKUP_EXPR_GLOBAL (in LOOKUP_EXPR).
TREE_NEGATED_INT (in INTEGER_CST). TREE_NEGATED_INT (in INTEGER_CST).
IDENTIFIER_MARKED (used by search routines). IDENTIFIER_MARKED (used by search routines).
LOCAL_BINDING_P (in CPLUS_BINDING)
1: IDENTIFIER_VIRTUAL_P. 1: IDENTIFIER_VIRTUAL_P.
TI_PENDING_TEMPLATE_FLAG. TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE. TEMPLATE_PARMS_FOR_INLINE.
...@@ -92,7 +93,8 @@ Boston, MA 02111-1307, USA. */ ...@@ -92,7 +93,8 @@ Boston, MA 02111-1307, USA. */
struct lang_identifier struct lang_identifier
{ {
struct tree_identifier ignore; struct tree_identifier ignore;
tree namespace_bindings, local_value; tree namespace_bindings;
tree bindings;
tree class_value; tree class_value;
tree class_template_info; tree class_template_info;
struct lang_id2 *x; struct lang_id2 *x;
...@@ -127,15 +129,24 @@ typedef struct ptrmem_cst ...@@ -127,15 +129,24 @@ typedef struct ptrmem_cst
tree member; tree member;
}* ptrmem_cst_t; }* ptrmem_cst_t;
/* For a binding between a name and an entity, defines the scope /* Nonzero if this binding is for a local scope, as opposed to a class
where the binding is declared. Currently always points to a or namespace scope. */
namespace declaration. */ #define LOCAL_BINDING_P(NODE) TREE_LANG_FLAG_0(NODE)
#define BINDING_SCOPE(NODE) (((struct tree_binding*)NODE)->scope)
/* For a binding between a name and an entity at a non-local scope,
defines the scope where the binding is declared. (Either a class
_TYPE node, or a NAMESPACE_DECL.) This macro should be used only
for namespace-level bindings; on the IDENTIFIER_BINDING list
BINDING_LEVEL is used instead. */
#define BINDING_SCOPE(NODE) ((tree) ((struct tree_binding*)NODE)->scope)
/* This is the declaration bound to the name. Possible values: /* This is the declaration bound to the name. Possible values:
variable, overloaded function, namespace, template, enumerator. */ variable, overloaded function, namespace, template, enumerator. */
#define BINDING_VALUE(NODE) (((struct tree_binding*)NODE)->value) #define BINDING_VALUE(NODE) (((struct tree_binding*)NODE)->value)
/* If name is bound to a type, this is the type (struct, union, enum). */ /* If name is bound to a type, this is the type (struct, union, enum). */
#define BINDING_TYPE(NODE) TREE_TYPE(NODE) #define BINDING_TYPE(NODE) TREE_TYPE(NODE)
#define IDENTIFIER_GLOBAL_VALUE(NODE) \ #define IDENTIFIER_GLOBAL_VALUE(NODE) \
namespace_binding (NODE, global_namespace) namespace_binding (NODE, global_namespace)
#define SET_IDENTIFIER_GLOBAL_VALUE(NODE, VAL) \ #define SET_IDENTIFIER_GLOBAL_VALUE(NODE, VAL) \
...@@ -148,7 +159,7 @@ typedef struct ptrmem_cst ...@@ -148,7 +159,7 @@ typedef struct ptrmem_cst
struct tree_binding struct tree_binding
{ {
char common[sizeof (struct tree_common)]; char common[sizeof (struct tree_common)];
tree scope; void* scope;
tree value; tree value;
}; };
...@@ -200,13 +211,43 @@ struct tree_srcloc ...@@ -200,13 +211,43 @@ struct tree_srcloc
#define IDENTIFIER_NAMESPACE_BINDINGS(NODE) \ #define IDENTIFIER_NAMESPACE_BINDINGS(NODE) \
(((struct lang_identifier *)(NODE))->namespace_bindings) (((struct lang_identifier *)(NODE))->namespace_bindings)
#define IDENTIFIER_CLASS_VALUE(NODE) \
(((struct lang_identifier *)(NODE))->class_value)
#define IDENTIFIER_LOCAL_VALUE(NODE) \
(((struct lang_identifier *)(NODE))->local_value)
#define IDENTIFIER_TEMPLATE(NODE) \ #define IDENTIFIER_TEMPLATE(NODE) \
(((struct lang_identifier *)(NODE))->class_template_info) (((struct lang_identifier *)(NODE))->class_template_info)
/* The IDENTIFIER_BINDING is the innermost CPLUS_BINDING for the
identifier. It's TREE_CHAIN is the next outermost binding. Each
BINDING_VALUE is a DECL for the associated declaration. Thus,
name lookup consists simply of pulling off the node at the front
of the list (modulo oddities for looking up the names of types,
and such.) You can use BINDING_SCOPE or BINDING_LEVEL to
determine the scope that bound the name. */
#define IDENTIFIER_BINDING(NODE) \
(((struct lang_identifier*) (NODE))->bindings)
/* The IDENTIFIER_VALUE is the value of the IDENTIFIER_BINDING, or
NULL_TREE if there is no binding. */
#define IDENTIFIER_VALUE(NODE) \
(IDENTIFIER_BINDING (NODE) \
? BINDING_VALUE (IDENTIFIER_BINDING (NODE)) \
: NULL_TREE)
/* If we are currently in class scope, then IDENTIFIER_CLASS_VALUE
indicates the class-scoped binding of NODE. This is just a pointer
to the BINDING_VALUE of one of the bindings in the
IDENTIFIER_BINDINGs list, so any time that this is set so is
IDENTIFIER_BINDING. */
#define IDENTIFIER_CLASS_VALUE(NODE) \
(((struct lang_identifier *) (NODE))->class_value)
/* The amount of time used by the file whose special "time identifier"
is NODE, represented as an INTEGER_CST. See get_time_identifier. */
#define TIME_IDENTIFIER_TIME(NODE) IDENTIFIER_BINDING(NODE)
/* For a "time identifier" this is a INTEGER_CST. The
TREE_INT_CST_LOW is 1 if the corresponding file is "interface only".
The TRE_INT_CST_HIGH is 1 if it is "interface unknown". */
#define TIME_IDENTIFIER_FILEINFO(NODE) IDENTIFIER_CLASS_VALUE (NODE)
/* TREE_TYPE only indicates on local and class scope the current /* TREE_TYPE only indicates on local and class scope the current
type. For namespace scope, the presence of a type in any namespace type. For namespace scope, the presence of a type in any namespace
is indicated with global_type_node, and the real type behind must is indicated with global_type_node, and the real type behind must
...@@ -1444,6 +1485,10 @@ struct lang_decl ...@@ -1444,6 +1485,10 @@ struct lang_decl
TEMPLATE_ID_EXPR if we had something like `typename X::Y<T>'. */ TEMPLATE_ID_EXPR if we had something like `typename X::Y<T>'. */
#define TYPENAME_TYPE_FULLNAME(NODE) TYPE_BINFO (NODE) #define TYPENAME_TYPE_FULLNAME(NODE) TYPE_BINFO (NODE)
/* Nonzero if NODE is an implicit typename. */
#define IMPLICIT_TYPENAME_P(NODE) \
(TREE_CODE (NODE) == TYPENAME_TYPE && TREE_TYPE (NODE))
/* Nonzero in INTEGER_CST means that this int is negative by dint of /* Nonzero in INTEGER_CST means that this int is negative by dint of
using a twos-complement negated operand. */ using a twos-complement negated operand. */
#define TREE_NEGATED_INT(NODE) (TREE_LANG_FLAG_0 (NODE)) #define TREE_NEGATED_INT(NODE) (TREE_LANG_FLAG_0 (NODE))
...@@ -2665,7 +2710,6 @@ extern void push_to_top_level PROTO((void)); ...@@ -2665,7 +2710,6 @@ extern void push_to_top_level PROTO((void));
extern void pop_from_top_level PROTO((void)); extern void pop_from_top_level PROTO((void));
extern tree identifier_type_value PROTO((tree)); extern tree identifier_type_value PROTO((tree));
extern void set_identifier_type_value PROTO((tree, tree)); extern void set_identifier_type_value PROTO((tree, tree));
extern void set_identifier_local_value PROTO((tree, tree));
extern void pop_everything PROTO((void)); extern void pop_everything PROTO((void));
extern void pushtag PROTO((tree, tree, int)); extern void pushtag PROTO((tree, tree, int));
extern tree make_anon_name PROTO((void)); extern tree make_anon_name PROTO((void));
...@@ -2761,6 +2805,8 @@ extern void revert_static_member_fn PROTO((tree*, tree*, tree*)); ...@@ -2761,6 +2805,8 @@ extern void revert_static_member_fn PROTO((tree*, tree*, tree*));
extern void cat_namespace_levels PROTO((void)); extern void cat_namespace_levels PROTO((void));
extern void fixup_anonymous_union PROTO((tree)); extern void fixup_anonymous_union PROTO((tree));
extern int check_static_variable_definition PROTO((tree, tree)); extern int check_static_variable_definition PROTO((tree, tree));
extern void push_local_binding PROTO((tree, tree));
extern void push_class_binding PROTO((tree, tree));
/* in decl2.c */ /* in decl2.c */
extern int check_java_method PROTO((tree)); extern int check_java_method PROTO((tree));
......
...@@ -4829,7 +4829,7 @@ do_local_using_decl (decl) ...@@ -4829,7 +4829,7 @@ do_local_using_decl (decl)
do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype); do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
if (newval) if (newval)
set_identifier_local_value (name, newval); push_local_binding (name, newval);
if (newtype) if (newtype)
set_identifier_type_value (name, newtype); set_identifier_type_value (name, newtype);
} }
......
...@@ -84,6 +84,7 @@ static int reduce_cmp PROTO((int *, int *)); ...@@ -84,6 +84,7 @@ static int reduce_cmp PROTO((int *, int *));
static int token_cmp PROTO((int *, int *)); static int token_cmp PROTO((int *, int *));
#endif #endif
#endif #endif
static void begin_definition_of_inclass_inline PROTO((struct pending_inline*));
/* Given a file name X, return the nondirectory portion. /* Given a file name X, return the nondirectory portion.
Keep in mind that X can be computed more than once. */ Keep in mind that X can be computed more than once. */
...@@ -322,12 +323,13 @@ get_time_identifier (name) ...@@ -322,12 +323,13 @@ get_time_identifier (name)
bcopy (name, buf+5, len); bcopy (name, buf+5, len);
buf[len+5] = '\0'; buf[len+5] = '\0';
time_identifier = get_identifier (buf); time_identifier = get_identifier (buf);
if (IDENTIFIER_LOCAL_VALUE (time_identifier) == NULL_TREE) if (TIME_IDENTIFIER_TIME (time_identifier) == NULL_TREE)
{ {
push_obstacks_nochange (); push_obstacks_nochange ();
end_temporary_allocation (); end_temporary_allocation ();
IDENTIFIER_LOCAL_VALUE (time_identifier) = build_int_2 (0, 0); TIME_IDENTIFIER_TIME (time_identifier) = build_int_2 (0, 0);
IDENTIFIER_CLASS_VALUE (time_identifier) = build_int_2 (0, 1); TIME_IDENTIFIER_FILEINFO (time_identifier)
= build_int_2 (0, 1);
SET_IDENTIFIER_GLOBAL_VALUE (time_identifier, filename_times); SET_IDENTIFIER_GLOBAL_VALUE (time_identifier, filename_times);
filename_times = time_identifier; filename_times = time_identifier;
pop_obstacks (); pop_obstacks ();
...@@ -435,7 +437,8 @@ init_filename_times () ...@@ -435,7 +437,8 @@ init_filename_times ()
{ {
header_time = 0; header_time = 0;
body_time = my_get_run_time (); body_time = my_get_run_time ();
TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time)) = body_time; TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time))
= body_time;
} }
} }
...@@ -1145,7 +1148,7 @@ extract_interface_info () ...@@ -1145,7 +1148,7 @@ extract_interface_info ()
} }
if (!fileinfo) if (!fileinfo)
fileinfo = get_time_identifier (input_filename); fileinfo = get_time_identifier (input_filename);
fileinfo = IDENTIFIER_CLASS_VALUE (fileinfo); fileinfo = TIME_IDENTIFIER_FILEINFO (fileinfo);
interface_only = TREE_INT_CST_LOW (fileinfo); interface_only = TREE_INT_CST_LOW (fileinfo);
interface_unknown = TREE_INT_CST_HIGH (fileinfo); interface_unknown = TREE_INT_CST_HIGH (fileinfo);
} }
...@@ -1196,7 +1199,7 @@ set_typedecl_interface_info (prev, vars) ...@@ -1196,7 +1199,7 @@ set_typedecl_interface_info (prev, vars)
tree prev ATTRIBUTE_UNUSED, vars; tree prev ATTRIBUTE_UNUSED, vars;
{ {
tree id = get_time_identifier (DECL_SOURCE_FILE (vars)); tree id = get_time_identifier (DECL_SOURCE_FILE (vars));
tree fileinfo = IDENTIFIER_CLASS_VALUE (id); tree fileinfo = TIME_IDENTIFIER_FILEINFO (id);
tree type = TREE_TYPE (vars); tree type = TREE_TYPE (vars);
CLASSTYPE_INTERFACE_ONLY (type) = TREE_INT_CST_LOW (fileinfo) CLASSTYPE_INTERFACE_ONLY (type) = TREE_INT_CST_LOW (fileinfo)
...@@ -1222,6 +1225,37 @@ set_vardecl_interface_info (prev, vars) ...@@ -1222,6 +1225,37 @@ set_vardecl_interface_info (prev, vars)
return 0; return 0;
} }
/* Set up the state required to correctly handle the definition of the
inline function whose preparsed state has been saved in PI. */
static void
begin_definition_of_inclass_inline (pi)
struct pending_inline* pi;
{
tree context;
if (!pi->fndecl)
return;
/* If this is an inline function in a local class, we must make sure
that we save all pertinent information about the function
surrounding the local class. */
context = hack_decl_function_context (pi->fndecl);
if (context)
push_cp_function_context (context);
feed_input (pi->buf, pi->len);
lineno = pi->lineno;
input_filename = pi->filename;
yychar = PRE_PARSED_FUNCTION_DECL;
yylval.ttype = build_tree_list ((tree) pi, pi->fndecl);
/* Pass back a handle to the rest of the inline functions, so that they
can be processed later. */
DECL_PENDING_INLINE_INFO (pi->fndecl) = 0;
interface_unknown = pi->interface == 1;
interface_only = pi->interface == 0;
}
/* Called from the top level: if there are any pending inlines to /* Called from the top level: if there are any pending inlines to
do, set up to process them now. This function sets up the first function do, set up to process them now. This function sets up the first function
to be parsed; after it has been, the rule for fndef in parse.y will to be parsed; after it has been, the rule for fndef in parse.y will
...@@ -1231,7 +1265,6 @@ void ...@@ -1231,7 +1265,6 @@ void
do_pending_inlines () do_pending_inlines ()
{ {
struct pending_inline *t; struct pending_inline *t;
tree context;
/* Oops, we're still dealing with the last batch. */ /* Oops, we're still dealing with the last batch. */
if (yychar == PRE_PARSED_FUNCTION_DECL) if (yychar == PRE_PARSED_FUNCTION_DECL)
...@@ -1258,32 +1291,7 @@ do_pending_inlines () ...@@ -1258,32 +1291,7 @@ do_pending_inlines ()
return; return;
/* Now start processing the first inline function. */ /* Now start processing the first inline function. */
context = hack_decl_function_context (t->fndecl); begin_definition_of_inclass_inline (t);
if (context)
push_cp_function_context (context);
maybe_begin_member_template_processing (t->fndecl);
if (t->len > 0)
{
feed_input (t->buf, t->len);
lineno = t->lineno;
#if 0
if (input_filename != t->filename)
{
input_filename = t->filename;
/* Get interface/implementation back in sync. */
extract_interface_info ();
}
#else
input_filename = t->filename;
interface_unknown = t->interface == 1;
interface_only = t->interface == 0;
#endif
yychar = PRE_PARSED_FUNCTION_DECL;
}
/* Pass back a handle on the rest of the inline functions, so that they
can be processed later. */
yylval.ttype = build_tree_list ((tree) t, t->fndecl);
DECL_PENDING_INLINE_INFO (t->fndecl) = 0;
} }
static int nextchar = -1; static int nextchar = -1;
...@@ -1299,7 +1307,6 @@ process_next_inline (t) ...@@ -1299,7 +1307,6 @@ process_next_inline (t)
tree context; tree context;
struct pending_inline *i = (struct pending_inline *) TREE_PURPOSE (t); struct pending_inline *i = (struct pending_inline *) TREE_PURPOSE (t);
context = hack_decl_function_context (i->fndecl); context = hack_decl_function_context (i->fndecl);
maybe_end_member_template_processing ();
if (context) if (context)
pop_cp_function_context (context); pop_cp_function_context (context);
i = i->next; i = i->next;
...@@ -1317,24 +1324,8 @@ process_next_inline (t) ...@@ -1317,24 +1324,8 @@ process_next_inline (t)
} }
yychar = YYEMPTY; yychar = YYEMPTY;
end_input (); end_input ();
if (i && i->fndecl != NULL_TREE)
{
context = hack_decl_function_context (i->fndecl);
if (context)
push_cp_function_context (context);
maybe_begin_member_template_processing (i->fndecl);
feed_input (i->buf, i->len);
lineno = i->lineno;
input_filename = i->filename;
yychar = PRE_PARSED_FUNCTION_DECL;
yylval.ttype = build_tree_list ((tree) i, i->fndecl);
DECL_PENDING_INLINE_INFO (i->fndecl) = 0;
}
if (i) if (i)
{ begin_definition_of_inclass_inline (i);
interface_unknown = i->interface == 1;
interface_only = i->interface == 0;
}
else else
extract_interface_info (); extract_interface_info ();
} }
...@@ -2507,7 +2498,7 @@ linenum: ...@@ -2507,7 +2498,7 @@ linenum:
int this_time = my_get_run_time (); int this_time = my_get_run_time ();
tree time_identifier = get_time_identifier (TREE_STRING_POINTER (yylval.ttype)); tree time_identifier = get_time_identifier (TREE_STRING_POINTER (yylval.ttype));
header_time += this_time - body_time; header_time += this_time - body_time;
TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time)) TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time))
+= this_time - body_time; += this_time - body_time;
this_filename_time = time_identifier; this_filename_time = time_identifier;
body_time = this_time; body_time = this_time;
...@@ -2943,11 +2934,9 @@ do_identifier (token, parsing, args) ...@@ -2943,11 +2934,9 @@ do_identifier (token, parsing, args)
/* Do Koenig lookup if appropriate (inside templates we build lookup /* Do Koenig lookup if appropriate (inside templates we build lookup
expressions instead). */ expressions instead). */
if (args && !current_template_parms && (!id || is_global (id))) if (args && !current_template_parms && (!id || is_global (id)))
{ /* If we have arguments and we only found global names, do Koenig
/* If we have arguments and we only found global names, lookup. */
do Koenig lookup. */ id = lookup_arg_dependent (token, id, args);
id = lookup_arg_dependent (token, id, args);
}
/* Remember that this name has been used in the class definition, as per /* Remember that this name has been used in the class definition, as per
[class.scope0] */ [class.scope0] */
...@@ -3183,16 +3172,20 @@ identifier_typedecl_value (node) ...@@ -3183,16 +3172,20 @@ identifier_typedecl_value (node)
type = IDENTIFIER_TYPE_VALUE (node); type = IDENTIFIER_TYPE_VALUE (node);
if (type == NULL_TREE) if (type == NULL_TREE)
return NULL_TREE; return NULL_TREE;
#define do(X) \
{ \ if (IDENTIFIER_BINDING (node))
t = (X); \ {
if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type) \ t = IDENTIFIER_VALUE (node);
return t; \ if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type)
} return t;
do (IDENTIFIER_LOCAL_VALUE (node)); }
do (IDENTIFIER_CLASS_VALUE (node)); if (IDENTIFIER_NAMESPACE_VALUE (node))
do (IDENTIFIER_NAMESPACE_VALUE (node)); {
#undef do t = IDENTIFIER_NAMESPACE_VALUE (node);
if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type)
return t;
}
/* Will this one ever happen? */ /* Will this one ever happen? */
if (TYPE_MAIN_DECL (type)) if (TYPE_MAIN_DECL (type))
return TYPE_MAIN_DECL (type); return TYPE_MAIN_DECL (type);
...@@ -4737,7 +4730,7 @@ dump_time_statistics () ...@@ -4737,7 +4730,7 @@ dump_time_statistics ()
{ {
register tree prev = 0, decl, next; register tree prev = 0, decl, next;
int this_time = my_get_run_time (); int this_time = my_get_run_time ();
TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time)) TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time))
+= this_time - body_time; += this_time - body_time;
fprintf (stderr, "\n******\n"); fprintf (stderr, "\n******\n");
...@@ -4756,7 +4749,7 @@ dump_time_statistics () ...@@ -4756,7 +4749,7 @@ dump_time_statistics ()
for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl)) for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl))
print_time (IDENTIFIER_POINTER (decl), print_time (IDENTIFIER_POINTER (decl),
TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (decl))); TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (decl)));
} }
void void
...@@ -4847,7 +4840,8 @@ handle_cp_pragma (pname) ...@@ -4847,7 +4840,8 @@ handle_cp_pragma (pname)
} }
else if (! strcmp (pname, "interface")) else if (! strcmp (pname, "interface"))
{ {
tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename)); tree fileinfo
= TIME_IDENTIFIER_FILEINFO (get_time_identifier (input_filename));
char *main_filename = input_filename; char *main_filename = input_filename;
main_filename = file_name_nondirectory (main_filename); main_filename = file_name_nondirectory (main_filename);
...@@ -4882,7 +4876,7 @@ handle_cp_pragma (pname) ...@@ -4882,7 +4876,7 @@ handle_cp_pragma (pname)
#ifdef AUTO_IMPLEMENT #ifdef AUTO_IMPLEMENT
filename = file_name_nondirectory (main_input_filename); filename = file_name_nondirectory (main_input_filename);
fi = get_time_identifier (filename); fi = get_time_identifier (filename);
fi = IDENTIFIER_CLASS_VALUE (fi); fi = TIME_IDENTIFIER_FILEINFO (fi);
TREE_INT_CST_LOW (fi) = 0; TREE_INT_CST_LOW (fi) = 0;
TREE_INT_CST_HIGH (fi) = 1; TREE_INT_CST_HIGH (fi) = 1;
/* Get default. */ /* Get default. */
...@@ -4902,7 +4896,8 @@ handle_cp_pragma (pname) ...@@ -4902,7 +4896,8 @@ handle_cp_pragma (pname)
} }
else if (! strcmp (pname, "implementation")) else if (! strcmp (pname, "implementation"))
{ {
tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename)); tree fileinfo
= TIME_IDENTIFIER_FILEINFO (get_time_identifier (input_filename));
char *main_filename = main_input_filename ? main_input_filename : input_filename; char *main_filename = main_input_filename ? main_input_filename : input_filename;
main_filename = file_name_nondirectory (main_filename); main_filename = file_name_nondirectory (main_filename);
......
...@@ -236,7 +236,7 @@ empty_parms () ...@@ -236,7 +236,7 @@ empty_parms ()
%token <ttype> PRE_PARSED_CLASS_DECL DEFARG DEFARG_MARKER %token <ttype> PRE_PARSED_CLASS_DECL DEFARG DEFARG_MARKER
%type <ttype> component_constructor_declarator %type <ttype> component_constructor_declarator
%type <ttype> fn.def2 return_id fn.defpen constructor_declarator %type <ttype> fn.def2 return_id fn.defpen constructor_declarator
%type <itype> ctor_initializer_opt %type <itype> ctor_initializer_opt function_try_block
%type <ttype> named_class_head named_class_head_sans_basetype %type <ttype> named_class_head named_class_head_sans_basetype
%type <ttype> named_complex_class_head_sans_basetype %type <ttype> named_complex_class_head_sans_basetype
%type <ttype> unnamed_class_head %type <ttype> unnamed_class_head
...@@ -639,7 +639,11 @@ fndef: ...@@ -639,7 +639,11 @@ fndef:
fn.def1 maybe_return_init ctor_initializer_opt compstmt_or_error fn.def1 maybe_return_init ctor_initializer_opt compstmt_or_error
{ finish_function (lineno, (int)$3, 0); } { finish_function (lineno, (int)$3, 0); }
| fn.def1 maybe_return_init function_try_block | fn.def1 maybe_return_init function_try_block
{ } {
int nested = (hack_decl_function_context
(current_function_decl) != NULL_TREE);
finish_function (lineno, (int)$3, nested);
}
| fn.def1 maybe_return_init error | fn.def1 maybe_return_init error
{ } { }
; ;
...@@ -2037,7 +2041,7 @@ initlist: ...@@ -2037,7 +2041,7 @@ initlist:
fn.defpen: fn.defpen:
PRE_PARSED_FUNCTION_DECL PRE_PARSED_FUNCTION_DECL
{ start_function (NULL_TREE, TREE_VALUE ($1), { start_function (NULL_TREE, TREE_VALUE ($1),
NULL_TREE, 1); NULL_TREE, 2);
reinit_parse_for_function (); } reinit_parse_for_function (); }
pending_inline: pending_inline:
...@@ -2045,11 +2049,16 @@ pending_inline: ...@@ -2045,11 +2049,16 @@ pending_inline:
{ {
int nested = (hack_decl_function_context int nested = (hack_decl_function_context
(current_function_decl) != NULL_TREE); (current_function_decl) != NULL_TREE);
finish_function (lineno, (int)$3, nested); finish_function (lineno, (int)$3 | 2, nested);
process_next_inline ($1); process_next_inline ($1);
} }
| fn.defpen maybe_return_init function_try_block | fn.defpen maybe_return_init function_try_block
{ process_next_inline ($1); } {
int nested = (hack_decl_function_context
(current_function_decl) != NULL_TREE);
finish_function (lineno, (int)$3 | 2, nested);
process_next_inline ($1);
}
| fn.defpen maybe_return_init error | fn.defpen maybe_return_init error
{ process_next_inline ($1); } { process_next_inline ($1); }
; ;
...@@ -3339,10 +3348,8 @@ function_try_block: ...@@ -3339,10 +3348,8 @@ function_try_block:
} }
handler_seq handler_seq
{ {
int nested = (hack_decl_function_context
(current_function_decl) != NULL_TREE);
expand_end_all_catch (); expand_end_all_catch ();
finish_function (lineno, (int)$3, nested); $$ = $3;
} }
; ;
......
...@@ -426,14 +426,14 @@ maybe_end_member_template_processing () ...@@ -426,14 +426,14 @@ maybe_end_member_template_processing ()
template <class T> class C { template <class U> void f(U); } template <class T> class C { template <class U> void f(U); }
then neither C<int>::f<char> nor C<T>::f<double> is considered then neither C<int>::f<char> nor C<T>::f<double> is considered
to be a member template. */ to be a member template. But, `template <class U> void
C<int>::f(U)' is considered a member template. */
int int
is_member_template (t) is_member_template (t)
tree t; tree t;
{ {
if (TREE_CODE (t) != FUNCTION_DECL if (!DECL_FUNCTION_TEMPLATE_P (t))
&& !DECL_FUNCTION_TEMPLATE_P (t))
/* Anything that isn't a function or a template function is /* Anything that isn't a function or a template function is
certainly not a member template. */ certainly not a member template. */
return 0; return 0;
...@@ -442,31 +442,12 @@ is_member_template (t) ...@@ -442,31 +442,12 @@ is_member_template (t)
if (hack_decl_function_context (t)) if (hack_decl_function_context (t))
return 0; return 0;
if ((DECL_FUNCTION_MEMBER_P (t) return (DECL_FUNCTION_MEMBER_P (DECL_TEMPLATE_RESULT (t))
&& !DECL_TEMPLATE_SPECIALIZATION (t))
|| (TREE_CODE (t) == TEMPLATE_DECL
&& DECL_FUNCTION_MEMBER_P (DECL_TEMPLATE_RESULT (t))))
{
tree tmpl;
if (DECL_FUNCTION_TEMPLATE_P (t))
tmpl = t;
else if (DECL_TEMPLATE_INFO (t)
&& DECL_FUNCTION_TEMPLATE_P (DECL_TI_TEMPLATE (t)))
tmpl = DECL_TI_TEMPLATE (t);
else
tmpl = NULL_TREE;
if (tmpl
/* If there are more levels of template parameters than /* If there are more levels of template parameters than
there are template classes surrounding the declaration, there are template classes surrounding the declaration,
then we have a member template. */ then we have a member template. */
&& (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)) > && (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (t)) >
template_class_depth (DECL_CLASS_CONTEXT (t)))) template_class_depth (DECL_CLASS_CONTEXT (t))));
return 1;
}
return 0;
} }
#if 0 /* UNUSED */ #if 0 /* UNUSED */
...@@ -1487,28 +1468,27 @@ int comp_template_parms (parms1, parms2) ...@@ -1487,28 +1468,27 @@ int comp_template_parms (parms1, parms2)
} }
/* Returns 1 iff old_id is a template parameter. OLD_DECL is the decl /* Returns 1 iff DECL is a template parameter. */
from IDENTIFIER_LOCAL_VALUE (new identifier). */
int decl_template_parm_p (old_decl) int decl_template_parm_p (decl)
tree old_decl; tree decl;
{ {
/* For template template parms. */ /* For template template parms. */
if (TREE_CODE (old_decl) == TEMPLATE_DECL if (TREE_CODE (decl) == TEMPLATE_DECL
&& TREE_TYPE (old_decl) && TREE_TYPE (decl)
&& TREE_CODE (TREE_TYPE (old_decl)) == TEMPLATE_TEMPLATE_PARM) && TREE_CODE (TREE_TYPE (decl)) == TEMPLATE_TEMPLATE_PARM)
return 1; return 1;
/* For template type parms. */ /* For template type parms. */
if (TREE_CODE (old_decl) == TYPE_DECL if (TREE_CODE (decl) == TYPE_DECL
&& TREE_TYPE (old_decl) && TREE_TYPE (decl)
&& TREE_CODE (TREE_TYPE (old_decl)) == TEMPLATE_TYPE_PARM) && TREE_CODE (TREE_TYPE (decl)) == TEMPLATE_TYPE_PARM)
return 1; return 1;
/* For template non-type parms. */ /* For template non-type parms. */
if (TREE_CODE (old_decl) == CONST_DECL if (TREE_CODE (decl) == CONST_DECL
&& DECL_INITIAL (old_decl) && DECL_INITIAL (decl)
&& TREE_CODE (DECL_INITIAL (old_decl)) == TEMPLATE_PARM_INDEX) && TREE_CODE (DECL_INITIAL (decl)) == TEMPLATE_PARM_INDEX)
return 1; return 1;
return 0; return 0;
...@@ -1523,11 +1503,10 @@ void ...@@ -1523,11 +1503,10 @@ void
check_template_shadow (decl) check_template_shadow (decl)
tree decl; tree decl;
{ {
if (current_template_parms tree olddecl = IDENTIFIER_VALUE (DECL_NAME (decl));
&& IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)))
{
tree olddecl = IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl));
if (current_template_parms && olddecl)
{
/* We check for decl != olddecl to avoid bogus errors for using a /* We check for decl != olddecl to avoid bogus errors for using a
name inside a class. We check TPFI to avoid duplicate errors for name inside a class. We check TPFI to avoid duplicate errors for
inline member templates. */ inline member templates. */
...@@ -3423,9 +3402,9 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope) ...@@ -3423,9 +3402,9 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
if (TREE_CODE (d1) == IDENTIFIER_NODE) if (TREE_CODE (d1) == IDENTIFIER_NODE)
{ {
if (IDENTIFIER_LOCAL_VALUE (d1) if (IDENTIFIER_VALUE (d1)
&& DECL_TEMPLATE_TEMPLATE_PARM_P (IDENTIFIER_LOCAL_VALUE (d1))) && DECL_TEMPLATE_TEMPLATE_PARM_P (IDENTIFIER_VALUE (d1)))
template = IDENTIFIER_LOCAL_VALUE (d1); template = IDENTIFIER_VALUE (d1);
else else
{ {
if (context) if (context)
...@@ -3468,9 +3447,10 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope) ...@@ -3468,9 +3447,10 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
my_friendly_abort (272); my_friendly_abort (272);
/* With something like `template <class T> class X class X { ... };' /* With something like `template <class T> class X class X { ... };'
we could end up with D1 having nothing but an IDENTIFIER_LOCAL_VALUE. we could end up with D1 having nothing but an IDENTIFIER_VALUE.
We don't want to do that, but we have to deal with the situation, so We don't want to do that, but we have to deal with the situation,
let's give them some syntax errors to chew on instead of a crash. */ so let's give them some syntax errors to chew on instead of a
crash. */
if (! template) if (! template)
{ {
cp_error ("`%T' is not a template", d1); cp_error ("`%T' is not a template", d1);
...@@ -5434,11 +5414,9 @@ tsubst_decl (t, args, type, in_decl) ...@@ -5434,11 +5414,9 @@ tsubst_decl (t, args, type, in_decl)
if (member && !strncmp (OPERATOR_TYPENAME_FORMAT, if (member && !strncmp (OPERATOR_TYPENAME_FORMAT,
IDENTIFIER_POINTER (DECL_NAME (r)), IDENTIFIER_POINTER (DECL_NAME (r)),
sizeof (OPERATOR_TYPENAME_FORMAT) - 1)) sizeof (OPERATOR_TYPENAME_FORMAT) - 1))
{ /* Type-conversion operator. Reconstruct the name, in
/* Type-conversion operator. Reconstruct the name, in case it's the name of one of the template's parameters. */
case it's the name of one of the template's parameters. */ DECL_NAME (r) = build_typename_overload (TREE_TYPE (type));
DECL_NAME (r) = build_typename_overload (TREE_TYPE (type));
}
DECL_ARGUMENTS (r) = tsubst (DECL_ARGUMENTS (t), args, t); DECL_ARGUMENTS (r) = tsubst (DECL_ARGUMENTS (t), args, t);
DECL_MAIN_VARIANT (r) = r; DECL_MAIN_VARIANT (r) = r;
...@@ -5453,14 +5431,6 @@ tsubst_decl (t, args, type, in_decl) ...@@ -5453,14 +5431,6 @@ tsubst_decl (t, args, type, in_decl)
DECL_PENDING_INLINE_INFO (r) = 0; DECL_PENDING_INLINE_INFO (r) = 0;
TREE_USED (r) = 0; TREE_USED (r) = 0;
if (DECL_CONSTRUCTOR_P (r))
{
maybe_retrofit_in_chrg (r);
grok_ctor_properties (ctx, r);
}
if (IDENTIFIER_OPNAME_P (DECL_NAME (r)))
grok_op_properties (r, DECL_VIRTUAL_P (r), DECL_FRIEND_P (r));
/* Set up the DECL_TEMPLATE_INFO for R and compute its mangled /* Set up the DECL_TEMPLATE_INFO for R and compute its mangled
name. There's no need to do this in the special friend name. There's no need to do this in the special friend
case mentioned above where GEN_TMPL is NULL. */ case mentioned above where GEN_TMPL is NULL. */
...@@ -5507,6 +5477,14 @@ tsubst_decl (t, args, type, in_decl) ...@@ -5507,6 +5477,14 @@ tsubst_decl (t, args, type, in_decl)
== NULL_TREE)) == NULL_TREE))
SET_IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (r), r); SET_IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (r), r);
} }
if (DECL_CONSTRUCTOR_P (r))
{
maybe_retrofit_in_chrg (r);
grok_ctor_properties (ctx, r);
}
if (IDENTIFIER_OPNAME_P (DECL_NAME (r)))
grok_op_properties (r, DECL_VIRTUAL_P (r), DECL_FRIEND_P (r));
} }
break; break;
...@@ -7688,11 +7666,12 @@ unify (tparms, targs, parm, arg, strict, explicit_mask) ...@@ -7688,11 +7666,12 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
} }
case RECORD_TYPE: case RECORD_TYPE:
case UNION_TYPE:
if (TYPE_PTRMEMFUNC_FLAG (parm)) if (TYPE_PTRMEMFUNC_FLAG (parm))
return unify (tparms, targs, TYPE_PTRMEMFUNC_FN_TYPE (parm), return unify (tparms, targs, TYPE_PTRMEMFUNC_FN_TYPE (parm),
arg, strict, explicit_mask); arg, strict, explicit_mask);
if (TREE_CODE (arg) != RECORD_TYPE) if (TREE_CODE (arg) != TREE_CODE (parm))
return 1; return 1;
if (CLASSTYPE_TEMPLATE_INFO (parm) && uses_template_parms (parm)) if (CLASSTYPE_TEMPLATE_INFO (parm) && uses_template_parms (parm))
......
...@@ -152,7 +152,7 @@ print_lang_identifier (file, node, indent) ...@@ -152,7 +152,7 @@ print_lang_identifier (file, node, indent)
{ {
print_node (file, "bindings", IDENTIFIER_NAMESPACE_BINDINGS (node), indent + 4); print_node (file, "bindings", IDENTIFIER_NAMESPACE_BINDINGS (node), indent + 4);
print_node (file, "class", IDENTIFIER_CLASS_VALUE (node), indent + 4); print_node (file, "class", IDENTIFIER_CLASS_VALUE (node), indent + 4);
print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4); print_node (file, "local bindings", IDENTIFIER_BINDING (node), indent + 4);
print_node (file, "label", IDENTIFIER_LABEL_VALUE (node), indent + 4); print_node (file, "label", IDENTIFIER_LABEL_VALUE (node), indent + 4);
print_node (file, "template", IDENTIFIER_TEMPLATE (node), indent + 4); print_node (file, "template", IDENTIFIER_TEMPLATE (node), indent + 4);
print_node (file, "implicit", IDENTIFIER_IMPLICIT_DECL (node), indent + 4); print_node (file, "implicit", IDENTIFIER_IMPLICIT_DECL (node), indent + 4);
...@@ -168,7 +168,8 @@ lang_print_xnode (file, node, indent) ...@@ -168,7 +168,8 @@ lang_print_xnode (file, node, indent)
switch (TREE_CODE (node)) switch (TREE_CODE (node))
{ {
case CPLUS_BINDING: case CPLUS_BINDING:
print_node (file, "scope", BINDING_SCOPE (node), indent+4); fprintf (file, " scope ");
fprintf (file, HOST_PTR_PRINTF, BINDING_SCOPE (node));
print_node (file, "value", BINDING_VALUE (node), indent+4); print_node (file, "value", BINDING_VALUE (node), indent+4);
print_node (file, "chain", TREE_CHAIN (node), indent+4); print_node (file, "chain", TREE_CHAIN (node), indent+4);
break; break;
......
...@@ -4849,7 +4849,8 @@ mark_addressable (exp) ...@@ -4849,7 +4849,8 @@ mark_addressable (exp)
TREE_ASM_WRITTEN (x) = 0; TREE_ASM_WRITTEN (x) = 0;
DECL_RTL (x) = 0; DECL_RTL (x) = 0;
rest_of_decl_compilation (x, 0, IDENTIFIER_LOCAL_VALUE (x) == 0, rest_of_decl_compilation (x, 0,
!DECL_FUNCTION_SCOPE_P (x),
0); 0);
TREE_ADDRESSABLE (x) = 1; TREE_ADDRESSABLE (x) = 1;
...@@ -7235,9 +7236,9 @@ c_expand_return (retval) ...@@ -7235,9 +7236,9 @@ c_expand_return (retval)
if (TEMP_NAME_P (DECL_NAME (whats_returned))) if (TEMP_NAME_P (DECL_NAME (whats_returned)))
warning ("reference to non-lvalue returned"); warning ("reference to non-lvalue returned");
else if (TREE_CODE (TREE_TYPE (whats_returned)) != REFERENCE_TYPE else if (TREE_CODE (TREE_TYPE (whats_returned)) != REFERENCE_TYPE
&& ! TREE_STATIC (whats_returned) && DECL_FUNCTION_SCOPE_P (whats_returned)
&& IDENTIFIER_LOCAL_VALUE (DECL_NAME (whats_returned)) && !(TREE_STATIC (whats_returned)
&& !TREE_PUBLIC (whats_returned)) || TREE_PUBLIC (whats_returned)))
cp_warning_at ("reference to local variable `%D' returned", whats_returned); cp_warning_at ("reference to local variable `%D' returned", whats_returned);
} }
} }
...@@ -7247,9 +7248,9 @@ c_expand_return (retval) ...@@ -7247,9 +7248,9 @@ c_expand_return (retval)
if (TREE_CODE (whats_returned) == VAR_DECL if (TREE_CODE (whats_returned) == VAR_DECL
&& DECL_NAME (whats_returned) && DECL_NAME (whats_returned)
&& IDENTIFIER_LOCAL_VALUE (DECL_NAME (whats_returned)) && DECL_FUNCTION_SCOPE_P (whats_returned)
&& !TREE_STATIC (whats_returned) && !(TREE_STATIC (whats_returned)
&& !TREE_PUBLIC (whats_returned)) || TREE_PUBLIC (whats_returned)))
cp_warning_at ("address of local variable `%D' returned", whats_returned); cp_warning_at ("address of local variable `%D' returned", whats_returned);
} }
} }
......
...@@ -8,11 +8,11 @@ ...@@ -8,11 +8,11 @@
// cfront 2.0 passes this test. // cfront 2.0 passes this test.
enum enum0 { enum0_value_0 }; // ERROR - enum enum0 { enum0_value_0 };
struct struct0 { struct struct0 {
int enum0; // ERROR - int enum0;
void member_function (enum0 e); void member_function (enum0 e); // ERROR -
}; };
void class0::member_function (enum0 e) { // ERROR - void class0::member_function (enum0 e) { // ERROR -
......
...@@ -6,11 +6,11 @@ ...@@ -6,11 +6,11 @@
// keywords: typedef names, shadowing, scope, formal parameter list // keywords: typedef names, shadowing, scope, formal parameter list
class class0; // ERROR - class class0;
struct struct1 { struct struct1 {
int class0; // ERROR - int class0;
void member_function (class0 *); void member_function (class0 *); // ERROR -
}; };
void class1::member_function (class0 *p) { // ERROR - void class1::member_function (class0 *p) { // ERROR -
......
// Build don't link:
int i;
int j;
struct S {
int operator()(int)
{
i = 1;
}
typedef int I;
void f() {
for (S I; false; )
;
int k = I(3);
}
};
typedef int J;
struct T {
int operator()(int)
{
j = 1;
}
void f() {
for (T J; false; )
;
int k = J(3);
}
};
int main()
{
S s;
s.f();
return 2 * i + j;
}
int f(int i)
{
struct C {
int i;
C () : i(1) {}
int f() {
struct D {
int i;
D () : i(2) {}
int g() { return i; }
} d;
return d.g();
}
} c;
return c.f();
}
int main()
{
if (f(0) != 2)
return 1;
}
struct T { ~T() {}; };
int g ()
{
foo:
T t;
int f(int);
bar:
T t2;
int f(double);
return f(3);
}
int f(int)
{
return 0;
}
int f(double)
{
return 1;
}
int main()
{
return g();
}
int i = 0;
template <class T>
class F
{
public:
F() {}
template <class T2> F(F<T2>)
{
i = 1;
}
};
F<int>
foo()
{
F<int> f1;
F<int> f2(f1);
return f1;
}
int
main()
{
return i;
}
// Build don't link: // Build don't link:
// excess errors test - XFAIL *-*-* // excess errors test
// This testcase won't fail if class ::foo is forward-declared in the // This testcase won't fail if class ::foo is forward-declared in the
// global namespace, nor if class bar is not a template class. // global namespace, nor if class bar is not a template class.
......
// Build don't link:
union Un {int i;};
template<class T1, class T2> struct St1 {};
template<class T> struct St1<Un,T> {};
template<class T> struct St2 {};
template<> struct St2<Un> {};
template<class T1, class T2> struct St3 {};
template<> struct St3<Un,int> {};
void f() {
St1<int,int> s1;
St2<int> s2;
St3<int,int> s3;
}
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