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
This commit is contained in:
Mark Mitchell 1998-12-13 14:46:07 +00:00 committed by Mark Mitchell
parent 92c068d1dc
commit f181d4aea0
19 changed files with 985 additions and 613 deletions

View File

@ -1,3 +1,84 @@
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>
* decl.c (grokdeclarator): Allow field with same name as class

View File

@ -4780,15 +4780,18 @@ pushclass (type, modify)
{
tree item;
/* Hooray, we successfully cached; let's just install the
cached class_shadowed list, and walk through it to get the
IDENTIFIER_TYPE_VALUEs correct. */
/* We are re-entering the same class we just left, so we
don't have to search the whole inheritance matrix to find
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);
for (item = previous_class_values; item; item = TREE_CHAIN (item))
{
tree id = TREE_PURPOSE (item);
tree decl = IDENTIFIER_CLASS_VALUE (id);
push_class_binding (id, decl);
if (TREE_CODE (decl) == TYPE_DECL)
set_identifier_type_value (id, TREE_TYPE (decl));
}

View File

@ -178,9 +178,9 @@ DEFTREECODE (DEFAULT_ARG, "default_arg", 'c', 2)
the template may be an IDENTIFIER_NODE. */
DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2)
/* An association between namespace and entity. Parameters are the
scope and the (non-type) value.
TREE_TYPE indicates the type bound to the name. */
/* An association between name and entity. Parameters are the scope
and the (non-type) value. TREE_TYPE indicates the type bound to
the name. */
DEFTREECODE (CPLUS_BINDING, "binding", 'x', 2)
/* A list-like node for chaining overloading candidates. TREE_TYPE is

View File

@ -31,6 +31,7 @@ Boston, MA 02111-1307, USA. */
LOOKUP_EXPR_GLOBAL (in LOOKUP_EXPR).
TREE_NEGATED_INT (in INTEGER_CST).
IDENTIFIER_MARKED (used by search routines).
LOCAL_BINDING_P (in CPLUS_BINDING)
1: IDENTIFIER_VIRTUAL_P.
TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE.
@ -92,7 +93,8 @@ Boston, MA 02111-1307, USA. */
struct lang_identifier
{
struct tree_identifier ignore;
tree namespace_bindings, local_value;
tree namespace_bindings;
tree bindings;
tree class_value;
tree class_template_info;
struct lang_id2 *x;
@ -127,15 +129,24 @@ typedef struct ptrmem_cst
tree member;
}* ptrmem_cst_t;
/* For a binding between a name and an entity, defines the scope
where the binding is declared. Currently always points to a
namespace declaration. */
#define BINDING_SCOPE(NODE) (((struct tree_binding*)NODE)->scope)
/* Nonzero if this binding is for a local scope, as opposed to a class
or namespace scope. */
#define LOCAL_BINDING_P(NODE) TREE_LANG_FLAG_0(NODE)
/* 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:
variable, overloaded function, namespace, template, enumerator. */
#define BINDING_VALUE(NODE) (((struct tree_binding*)NODE)->value)
/* If name is bound to a type, this is the type (struct, union, enum). */
#define BINDING_TYPE(NODE) TREE_TYPE(NODE)
#define IDENTIFIER_GLOBAL_VALUE(NODE) \
namespace_binding (NODE, global_namespace)
#define SET_IDENTIFIER_GLOBAL_VALUE(NODE, VAL) \
@ -148,7 +159,7 @@ typedef struct ptrmem_cst
struct tree_binding
{
char common[sizeof (struct tree_common)];
tree scope;
void* scope;
tree value;
};
@ -200,13 +211,43 @@ struct tree_srcloc
#define IDENTIFIER_NAMESPACE_BINDINGS(NODE) \
(((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) \
(((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
type. For namespace scope, the presence of a type in any namespace
is indicated with global_type_node, and the real type behind must
@ -1444,6 +1485,10 @@ struct lang_decl
TEMPLATE_ID_EXPR if we had something like `typename X::Y<T>'. */
#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
using a twos-complement negated operand. */
#define TREE_NEGATED_INT(NODE) (TREE_LANG_FLAG_0 (NODE))
@ -2665,7 +2710,6 @@ extern void push_to_top_level PROTO((void));
extern void pop_from_top_level PROTO((void));
extern tree identifier_type_value PROTO((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 pushtag PROTO((tree, tree, int));
extern tree make_anon_name PROTO((void));
@ -2761,6 +2805,8 @@ extern void revert_static_member_fn PROTO((tree*, tree*, tree*));
extern void cat_namespace_levels PROTO((void));
extern void fixup_anonymous_union PROTO((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 */
extern int check_java_method PROTO((tree));

File diff suppressed because it is too large Load Diff

View File

@ -4829,7 +4829,7 @@ do_local_using_decl (decl)
do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
if (newval)
set_identifier_local_value (name, newval);
push_local_binding (name, newval);
if (newtype)
set_identifier_type_value (name, newtype);
}

View File

@ -84,6 +84,7 @@ static int reduce_cmp PROTO((int *, int *));
static int token_cmp PROTO((int *, int *));
#endif
#endif
static void begin_definition_of_inclass_inline PROTO((struct pending_inline*));
/* Given a file name X, return the nondirectory portion.
Keep in mind that X can be computed more than once. */
@ -322,12 +323,13 @@ get_time_identifier (name)
bcopy (name, buf+5, len);
buf[len+5] = '\0';
time_identifier = get_identifier (buf);
if (IDENTIFIER_LOCAL_VALUE (time_identifier) == NULL_TREE)
if (TIME_IDENTIFIER_TIME (time_identifier) == NULL_TREE)
{
push_obstacks_nochange ();
end_temporary_allocation ();
IDENTIFIER_LOCAL_VALUE (time_identifier) = build_int_2 (0, 0);
IDENTIFIER_CLASS_VALUE (time_identifier) = build_int_2 (0, 1);
TIME_IDENTIFIER_TIME (time_identifier) = build_int_2 (0, 0);
TIME_IDENTIFIER_FILEINFO (time_identifier)
= build_int_2 (0, 1);
SET_IDENTIFIER_GLOBAL_VALUE (time_identifier, filename_times);
filename_times = time_identifier;
pop_obstacks ();
@ -435,7 +437,8 @@ init_filename_times ()
{
header_time = 0;
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 ()
}
if (!fileinfo)
fileinfo = get_time_identifier (input_filename);
fileinfo = IDENTIFIER_CLASS_VALUE (fileinfo);
fileinfo = TIME_IDENTIFIER_FILEINFO (fileinfo);
interface_only = TREE_INT_CST_LOW (fileinfo);
interface_unknown = TREE_INT_CST_HIGH (fileinfo);
}
@ -1196,7 +1199,7 @@ set_typedecl_interface_info (prev, vars)
tree prev ATTRIBUTE_UNUSED, 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);
CLASSTYPE_INTERFACE_ONLY (type) = TREE_INT_CST_LOW (fileinfo)
@ -1222,6 +1225,37 @@ set_vardecl_interface_info (prev, vars)
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
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
@ -1231,7 +1265,6 @@ void
do_pending_inlines ()
{
struct pending_inline *t;
tree context;
/* Oops, we're still dealing with the last batch. */
if (yychar == PRE_PARSED_FUNCTION_DECL)
@ -1258,32 +1291,7 @@ do_pending_inlines ()
return;
/* Now start processing the first inline function. */
context = hack_decl_function_context (t->fndecl);
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;
begin_definition_of_inclass_inline (t);
}
static int nextchar = -1;
@ -1299,7 +1307,6 @@ process_next_inline (t)
tree context;
struct pending_inline *i = (struct pending_inline *) TREE_PURPOSE (t);
context = hack_decl_function_context (i->fndecl);
maybe_end_member_template_processing ();
if (context)
pop_cp_function_context (context);
i = i->next;
@ -1317,24 +1324,8 @@ process_next_inline (t)
}
yychar = YYEMPTY;
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)
{
interface_unknown = i->interface == 1;
interface_only = i->interface == 0;
}
begin_definition_of_inclass_inline (i);
else
extract_interface_info ();
}
@ -2507,7 +2498,7 @@ linenum:
int this_time = my_get_run_time ();
tree time_identifier = get_time_identifier (TREE_STRING_POINTER (yylval.ttype));
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_filename_time = time_identifier;
body_time = this_time;
@ -2943,11 +2934,9 @@ do_identifier (token, parsing, args)
/* Do Koenig lookup if appropriate (inside templates we build lookup
expressions instead). */
if (args && !current_template_parms && (!id || is_global (id)))
{
/* If we have arguments and we only found global names,
do Koenig lookup. */
id = lookup_arg_dependent (token, id, args);
}
/* If we have arguments and we only found global names, do Koenig
lookup. */
id = lookup_arg_dependent (token, id, args);
/* Remember that this name has been used in the class definition, as per
[class.scope0] */
@ -3183,16 +3172,20 @@ identifier_typedecl_value (node)
type = IDENTIFIER_TYPE_VALUE (node);
if (type == NULL_TREE)
return NULL_TREE;
#define do(X) \
{ \
t = (X); \
if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type) \
return t; \
}
do (IDENTIFIER_LOCAL_VALUE (node));
do (IDENTIFIER_CLASS_VALUE (node));
do (IDENTIFIER_NAMESPACE_VALUE (node));
#undef do
if (IDENTIFIER_BINDING (node))
{
t = IDENTIFIER_VALUE (node);
if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type)
return t;
}
if (IDENTIFIER_NAMESPACE_VALUE (node))
{
t = IDENTIFIER_NAMESPACE_VALUE (node);
if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type)
return t;
}
/* Will this one ever happen? */
if (TYPE_MAIN_DECL (type))
return TYPE_MAIN_DECL (type);
@ -4737,7 +4730,7 @@ dump_time_statistics ()
{
register tree prev = 0, decl, next;
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;
fprintf (stderr, "\n******\n");
@ -4756,7 +4749,7 @@ dump_time_statistics ()
for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl))
print_time (IDENTIFIER_POINTER (decl),
TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (decl)));
TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (decl)));
}
void
@ -4847,7 +4840,8 @@ handle_cp_pragma (pname)
}
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;
main_filename = file_name_nondirectory (main_filename);
@ -4882,7 +4876,7 @@ handle_cp_pragma (pname)
#ifdef AUTO_IMPLEMENT
filename = file_name_nondirectory (main_input_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_HIGH (fi) = 1;
/* Get default. */
@ -4902,7 +4896,8 @@ handle_cp_pragma (pname)
}
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;
main_filename = file_name_nondirectory (main_filename);

View File

@ -236,7 +236,7 @@ empty_parms ()
%token <ttype> PRE_PARSED_CLASS_DECL DEFARG DEFARG_MARKER
%type <ttype> component_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_complex_class_head_sans_basetype
%type <ttype> unnamed_class_head
@ -639,7 +639,11 @@ fndef:
fn.def1 maybe_return_init ctor_initializer_opt compstmt_or_error
{ finish_function (lineno, (int)$3, 0); }
| 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
{ }
;
@ -2037,7 +2041,7 @@ initlist:
fn.defpen:
PRE_PARSED_FUNCTION_DECL
{ start_function (NULL_TREE, TREE_VALUE ($1),
NULL_TREE, 1);
NULL_TREE, 2);
reinit_parse_for_function (); }
pending_inline:
@ -2045,11 +2049,16 @@ pending_inline:
{
int nested = (hack_decl_function_context
(current_function_decl) != NULL_TREE);
finish_function (lineno, (int)$3, nested);
finish_function (lineno, (int)$3 | 2, nested);
process_next_inline ($1);
}
| 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
{ process_next_inline ($1); }
;
@ -3339,10 +3348,8 @@ function_try_block:
}
handler_seq
{
int nested = (hack_decl_function_context
(current_function_decl) != NULL_TREE);
expand_end_all_catch ();
finish_function (lineno, (int)$3, nested);
$$ = $3;
}
;

View File

@ -426,14 +426,14 @@ maybe_end_member_template_processing ()
template <class T> class C { template <class U> void f(U); }
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
is_member_template (t)
tree t;
{
if (TREE_CODE (t) != FUNCTION_DECL
&& !DECL_FUNCTION_TEMPLATE_P (t))
if (!DECL_FUNCTION_TEMPLATE_P (t))
/* Anything that isn't a function or a template function is
certainly not a member template. */
return 0;
@ -442,31 +442,12 @@ is_member_template (t)
if (hack_decl_function_context (t))
return 0;
if ((DECL_FUNCTION_MEMBER_P (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
return (DECL_FUNCTION_MEMBER_P (DECL_TEMPLATE_RESULT (t))
/* If there are more levels of template parameters than
there are template classes surrounding the declaration,
then we have a member template. */
&& (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)) >
template_class_depth (DECL_CLASS_CONTEXT (t))))
return 1;
}
return 0;
&& (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (t)) >
template_class_depth (DECL_CLASS_CONTEXT (t))));
}
#if 0 /* UNUSED */
@ -1487,28 +1468,27 @@ int comp_template_parms (parms1, parms2)
}
/* Returns 1 iff old_id is a template parameter. OLD_DECL is the decl
from IDENTIFIER_LOCAL_VALUE (new identifier). */
/* Returns 1 iff DECL is a template parameter. */
int decl_template_parm_p (old_decl)
tree old_decl;
int decl_template_parm_p (decl)
tree decl;
{
/* For template template parms. */
if (TREE_CODE (old_decl) == TEMPLATE_DECL
&& TREE_TYPE (old_decl)
&& TREE_CODE (TREE_TYPE (old_decl)) == TEMPLATE_TEMPLATE_PARM)
if (TREE_CODE (decl) == TEMPLATE_DECL
&& TREE_TYPE (decl)
&& TREE_CODE (TREE_TYPE (decl)) == TEMPLATE_TEMPLATE_PARM)
return 1;
/* For template type parms. */
if (TREE_CODE (old_decl) == TYPE_DECL
&& TREE_TYPE (old_decl)
&& TREE_CODE (TREE_TYPE (old_decl)) == TEMPLATE_TYPE_PARM)
if (TREE_CODE (decl) == TYPE_DECL
&& TREE_TYPE (decl)
&& TREE_CODE (TREE_TYPE (decl)) == TEMPLATE_TYPE_PARM)
return 1;
/* For template non-type parms. */
if (TREE_CODE (old_decl) == CONST_DECL
&& DECL_INITIAL (old_decl)
&& TREE_CODE (DECL_INITIAL (old_decl)) == TEMPLATE_PARM_INDEX)
if (TREE_CODE (decl) == CONST_DECL
&& DECL_INITIAL (decl)
&& TREE_CODE (DECL_INITIAL (decl)) == TEMPLATE_PARM_INDEX)
return 1;
return 0;
@ -1523,11 +1503,10 @@ void
check_template_shadow (decl)
tree decl;
{
if (current_template_parms
&& IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)))
{
tree olddecl = IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl));
tree olddecl = IDENTIFIER_VALUE (DECL_NAME (decl));
if (current_template_parms && olddecl)
{
/* We check for decl != olddecl to avoid bogus errors for using a
name inside a class. We check TPFI to avoid duplicate errors for
inline member templates. */
@ -3423,9 +3402,9 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
if (TREE_CODE (d1) == IDENTIFIER_NODE)
{
if (IDENTIFIER_LOCAL_VALUE (d1)
&& DECL_TEMPLATE_TEMPLATE_PARM_P (IDENTIFIER_LOCAL_VALUE (d1)))
template = IDENTIFIER_LOCAL_VALUE (d1);
if (IDENTIFIER_VALUE (d1)
&& DECL_TEMPLATE_TEMPLATE_PARM_P (IDENTIFIER_VALUE (d1)))
template = IDENTIFIER_VALUE (d1);
else
{
if (context)
@ -3468,9 +3447,10 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
my_friendly_abort (272);
/* With something like `template <class T> class X class X { ... };'
we could end up with D1 having nothing but an IDENTIFIER_LOCAL_VALUE.
We don't want to do that, but we have to deal with the situation, so
let's give them some syntax errors to chew on instead of a crash. */
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 let's give them some syntax errors to chew on instead of a
crash. */
if (! template)
{
cp_error ("`%T' is not a template", d1);
@ -5434,11 +5414,9 @@ tsubst_decl (t, args, type, in_decl)
if (member && !strncmp (OPERATOR_TYPENAME_FORMAT,
IDENTIFIER_POINTER (DECL_NAME (r)),
sizeof (OPERATOR_TYPENAME_FORMAT) - 1))
{
/* Type-conversion operator. Reconstruct the name, in
case it's the name of one of the template's parameters. */
DECL_NAME (r) = build_typename_overload (TREE_TYPE (type));
}
/* Type-conversion operator. Reconstruct the name, in
case it's the name of one of the template's parameters. */
DECL_NAME (r) = build_typename_overload (TREE_TYPE (type));
DECL_ARGUMENTS (r) = tsubst (DECL_ARGUMENTS (t), args, t);
DECL_MAIN_VARIANT (r) = r;
@ -5453,14 +5431,6 @@ tsubst_decl (t, args, type, in_decl)
DECL_PENDING_INLINE_INFO (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
name. There's no need to do this in the special friend
case mentioned above where GEN_TMPL is NULL. */
@ -5507,6 +5477,14 @@ tsubst_decl (t, args, type, in_decl)
== NULL_TREE))
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;
@ -7688,11 +7666,12 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
}
case RECORD_TYPE:
case UNION_TYPE:
if (TYPE_PTRMEMFUNC_FLAG (parm))
return unify (tparms, targs, TYPE_PTRMEMFUNC_FN_TYPE (parm),
arg, strict, explicit_mask);
if (TREE_CODE (arg) != RECORD_TYPE)
if (TREE_CODE (arg) != TREE_CODE (parm))
return 1;
if (CLASSTYPE_TEMPLATE_INFO (parm) && uses_template_parms (parm))

View File

@ -152,7 +152,7 @@ print_lang_identifier (file, node, indent)
{
print_node (file, "bindings", IDENTIFIER_NAMESPACE_BINDINGS (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, "template", IDENTIFIER_TEMPLATE (node), indent + 4);
print_node (file, "implicit", IDENTIFIER_IMPLICIT_DECL (node), indent + 4);
@ -168,7 +168,8 @@ lang_print_xnode (file, node, indent)
switch (TREE_CODE (node))
{
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, "chain", TREE_CHAIN (node), indent+4);
break;

View File

@ -4849,7 +4849,8 @@ mark_addressable (exp)
TREE_ASM_WRITTEN (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);
TREE_ADDRESSABLE (x) = 1;
@ -7235,9 +7236,9 @@ c_expand_return (retval)
if (TEMP_NAME_P (DECL_NAME (whats_returned)))
warning ("reference to non-lvalue returned");
else if (TREE_CODE (TREE_TYPE (whats_returned)) != REFERENCE_TYPE
&& ! TREE_STATIC (whats_returned)
&& IDENTIFIER_LOCAL_VALUE (DECL_NAME (whats_returned))
&& !TREE_PUBLIC (whats_returned))
&& DECL_FUNCTION_SCOPE_P (whats_returned)
&& !(TREE_STATIC (whats_returned)
|| TREE_PUBLIC (whats_returned)))
cp_warning_at ("reference to local variable `%D' returned", whats_returned);
}
}
@ -7247,9 +7248,9 @@ c_expand_return (retval)
if (TREE_CODE (whats_returned) == VAR_DECL
&& DECL_NAME (whats_returned)
&& IDENTIFIER_LOCAL_VALUE (DECL_NAME (whats_returned))
&& !TREE_STATIC (whats_returned)
&& !TREE_PUBLIC (whats_returned))
&& DECL_FUNCTION_SCOPE_P (whats_returned)
&& !(TREE_STATIC (whats_returned)
|| TREE_PUBLIC (whats_returned)))
cp_warning_at ("address of local variable `%D' returned", whats_returned);
}
}

View File

@ -8,11 +8,11 @@
// cfront 2.0 passes this test.
enum enum0 { enum0_value_0 }; // ERROR -
enum enum0 { enum0_value_0 };
struct struct0 {
int enum0; // ERROR -
void member_function (enum0 e);
int enum0;
void member_function (enum0 e); // ERROR -
};
void class0::member_function (enum0 e) { // ERROR -

View File

@ -6,11 +6,11 @@
// keywords: typedef names, shadowing, scope, formal parameter list
class class0; // ERROR -
class class0;
struct struct1 {
int class0; // ERROR -
void member_function (class0 *);
int class0;
void member_function (class0 *); // ERROR -
};
void class1::member_function (class0 *p) { // ERROR -

View File

@ -0,0 +1,41 @@
// 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;
}

View File

@ -0,0 +1,25 @@
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;
}

View File

@ -0,0 +1,31 @@
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();
}

View File

@ -0,0 +1,29 @@
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;
}

View File

@ -1,5 +1,5 @@
// Build don't link:
// excess errors test - XFAIL *-*-*
// excess errors test
// This testcase won't fail if class ::foo is forward-declared in the
// global namespace, nor if class bar is not a template class.

View File

@ -0,0 +1,18 @@
// 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;
}