Commit e2c3721c by Paolo Bonzini Committed by Paolo Bonzini

decl.c (cp_tree_node_structure): Kill TINST_LEVEL case.

2007-08-25  Paolo Bonzini  <bonzini@gnu.org>

	* decl.c (cp_tree_node_structure): Kill TINST_LEVEL case.
	* cp-objcp-common.c (cp_tree_size): Ditto.
	* tree.c (cp_walk_subtrees): Ditto
	* cp-tree.def (TINST_LEVEL): Go away.
	* cp-tree.h (struct tinst_level_s): Rename to struct tinst_level,
	move together with other non-tree structs.
	(enum cp_tree_node_structure_enum): Nuke TS_CP_TINST_LEVEL.
	(union lang_tree_node): Eliminate tinst_level field.
	(TINST_DECL, TINST_LOCATION, TINST_IN_SYSTEM_HEADER_P): Annihilate.
	(current_instantiation, outermost_tinst_level): Return
	a "struct tinst_level *".

	* error.c (print_instantiation_partial_context): Change second
	parameter to a "struct tinst_level *".  Replace accessor macros
	with field access.
	(print_instantiation_full_context): Likewise.
	* lex.c (in_main_input_context): Likewise.

	* pt.c (struct pending_templates): New.
	(pending_templates, last_pending_template): Use it as a type.
	(current_tinst_level): Change typo to "struct tinst_level *"
	(reopen_tinst_level): Accept "struct tinst_level *", return decl.
	(add_pending_template): Construct a "struct pending_template".
	Replace TINST_LEVEL accessor macros with field access.
	(push_tinst_level): Likewise, using GGC_NEW instead of make_node.
	(pop_tinst_level): Likewise.
	(instantiate_pending_templates): Likewise.  Factor common code used
	when an instantiation has been done.
	(outermost_tinst_level): Replace tree_last with loop.
	(current_instantiation): Return a "struct tinst_level *".

From-SVN: r127796
parent 65fedc2c
2007-08-25 Paolo Bonzini <bonzini@gnu.org>
* decl.c (cp_tree_node_structure): Kill TINST_LEVEL case.
* cp-objcp-common.c (cp_tree_size): Ditto.
* tree.c (cp_walk_subtrees): Ditto
* cp-tree.def (TINST_LEVEL): Go away.
* cp-tree.h (struct tinst_level_s): Rename to struct tinst_level,
move together with other non-tree structs.
(enum cp_tree_node_structure_enum): Nuke TS_CP_TINST_LEVEL.
(union lang_tree_node): Eliminate tinst_level field.
(TINST_DECL, TINST_LOCATION, TINST_IN_SYSTEM_HEADER_P): Annihilate.
(current_instantiation, outermost_tinst_level): Return
a "struct tinst_level *".
* error.c (print_instantiation_partial_context): Change second
parameter to a "struct tinst_level *". Replace accessor macros
with field access.
(print_instantiation_full_context): Likewise.
* lex.c (in_main_input_context): Likewise.
* pt.c (struct pending_templates): New.
(pending_templates, last_pending_template): Use it as a type.
(current_tinst_level): Change typo to "struct tinst_level *"
(reopen_tinst_level): Accept "struct tinst_level *", return decl.
(add_pending_template): Construct a "struct pending_template".
Replace TINST_LEVEL accessor macros with field access.
(push_tinst_level): Likewise, using GGC_NEW instead of make_node.
(pop_tinst_level): Likewise.
(instantiate_pending_templates): Likewise. Factor common code used
when an instantiation has been done.
(outermost_tinst_level): Replace tree_last with loop.
(current_instantiation): Return a "struct tinst_level *".
2007-08-24 Ollie Wild <aaw@google.com>
* name-lookup.c (add_decl_to_level): Remove addition to vtables chain.
......
......@@ -118,7 +118,6 @@ cp_tree_size (enum tree_code code)
{
switch (code)
{
case TINST_LEVEL: return sizeof (struct tinst_level_s);
case PTRMEM_CST: return sizeof (struct ptrmem_cst);
case BASELINK: return sizeof (struct tree_baselink);
case TEMPLATE_PARM_INDEX: return sizeof (template_parm_index);
......
......@@ -311,17 +311,6 @@ DEFTREECODE (EXPR_STMT, "expr_stmt", tcc_expression, 1)
DEFTREECODE (TAG_DEFN, "tag_defn", tcc_expression, 0)
/* Template instantiation level node.
TINST_DECL contains the original DECL node.
TINST_LOCATION contains the location where the template is instantiated.
TINST_IN_SYSTEM_HEADER_P is true if the location is in a system header.
A stack of template instantiation nodes is kept through the TREE_CHAIN
fields of these nodes. */
DEFTREECODE (TINST_LEVEL, "TINST_LEVEL", tcc_exceptional, 0)
/* Represents an 'offsetof' expression during template expansion. */
DEFTREECODE (OFFSETOF_EXPR, "offsetof_expr", tcc_expression, 1)
......
......@@ -229,15 +229,6 @@ struct template_parm_index_s GTY(())
};
typedef struct template_parm_index_s template_parm_index;
struct tinst_level_s GTY(())
{
struct tree_common common;
tree decl;
location_t locus;
int in_system_header_p;
};
typedef struct tinst_level_s * tinst_level_t;
struct ptrmem_cst GTY(())
{
struct tree_common common;
......@@ -527,7 +518,6 @@ enum cp_tree_node_structure_enum {
TS_CP_GENERIC,
TS_CP_IDENTIFIER,
TS_CP_TPI,
TS_CP_TINST_LEVEL,
TS_CP_PTRMEM,
TS_CP_BINDING,
TS_CP_OVERLOAD,
......@@ -547,7 +537,6 @@ union lang_tree_node GTY((desc ("cp_tree_node_structure (&%h)"),
union tree_node GTY ((tag ("TS_CP_GENERIC"),
desc ("tree_node_structure (&%h)"))) generic;
struct template_parm_index_s GTY ((tag ("TS_CP_TPI"))) tpi;
struct tinst_level_s GTY ((tag ("TS_CP_TINST_LEVEL"))) tinst_level;
struct ptrmem_cst GTY ((tag ("TS_CP_PTRMEM"))) ptrmem;
struct tree_overload GTY ((tag ("TS_CP_OVERLOAD"))) overload;
struct tree_baselink GTY ((tag ("TS_CP_BASELINK"))) baselink;
......@@ -3553,15 +3542,6 @@ typedef enum unification_kind_t {
DEDUCE_EXACT
} unification_kind_t;
/* Macros for operating on a template instantiation level node. */
#define TINST_DECL(NODE) \
(((tinst_level_t) TINST_LEVEL_CHECK (NODE))->decl)
#define TINST_LOCATION(NODE) \
(((tinst_level_t) TINST_LEVEL_CHECK (NODE))->locus)
#define TINST_IN_SYSTEM_HEADER_P(NODE) \
(((tinst_level_t) TINST_LEVEL_CHECK (NODE))->in_system_header_p)
/* in class.c */
extern int current_class_depth;
......@@ -4056,6 +4036,24 @@ struct cp_declarator {
} u;
};
/* A level of template instantiation. */
struct tinst_level GTY(())
{
/* The immediately deeper level in the chain. */
struct tinst_level *next;
/* The original node. Can be either a DECL (for a function or static
data member) or a TYPE (for a class), depending on what we were
asked to instantiate. */
tree decl;
/* The location where the template is instantiated. */
location_t locus;
/* True if the location is in a system header. */
bool in_system_header_p;
};
/* A parameter list indicating for a function with no parameters,
e.g "int f(void)". */
extern cp_parameter_declarator *no_parameters;
......@@ -4448,7 +4446,7 @@ extern tree most_general_template (tree);
extern tree get_mostly_instantiated_function_type (tree);
extern int problematic_instantiation_changed (void);
extern void record_last_problematic_instantiation (void);
extern tree current_instantiation (void);
extern struct tinst_level *current_instantiation(void);
extern tree maybe_get_template_decl_from_type_decl (tree);
extern int processing_template_parmlist;
extern bool dependent_type_p (tree);
......@@ -4466,7 +4464,7 @@ extern tree build_non_dependent_args (tree);
extern bool reregister_specialization (tree, tree, tree);
extern tree fold_non_dependent_expr (tree);
extern bool explicit_class_specialization_p (tree);
extern tree outermost_tinst_level (void);
extern struct tinst_level *outermost_tinst_level(void);
/* in repo.c */
extern void init_repo (void);
......
......@@ -12025,7 +12025,6 @@ cp_tree_node_structure (union lang_tree_node * t)
case IDENTIFIER_NODE: return TS_CP_IDENTIFIER;
case OVERLOAD: return TS_CP_OVERLOAD;
case TEMPLATE_PARM_INDEX: return TS_CP_TPI;
case TINST_LEVEL: return TS_CP_TINST_LEVEL;
case PTRMEM_CST: return TS_CP_PTRMEM;
case BASELINK: return TS_CP_BASELINK;
case STATIC_ASSERT: return TS_CP_STATIC_ASSERT;
......
......@@ -82,7 +82,8 @@ static const char *function_category (tree);
static void maybe_print_instantiation_context (diagnostic_context *);
static void print_instantiation_full_context (diagnostic_context *);
static void print_instantiation_partial_context (diagnostic_context *,
tree, location_t);
struct tinst_level *,
location_t);
static void cp_diagnostic_starter (diagnostic_context *, diagnostic_info *);
static void cp_diagnostic_finalizer (diagnostic_context *, diagnostic_info *);
static void cp_print_error_function (diagnostic_context *, diagnostic_info *);
......@@ -2388,30 +2389,30 @@ function_category (tree fn)
static void
print_instantiation_full_context (diagnostic_context *context)
{
tree p = current_instantiation ();
struct tinst_level *p = current_instantiation ();
location_t location = input_location;
if (p)
{
if (current_function_decl != TINST_DECL (p)
if (current_function_decl != p->decl
&& current_function_decl != NULL_TREE)
/* We can get here during the processing of some synthesized
method. Then, TINST_DECL (p) will be the function that's causing
method. Then, P->DECL will be the function that's causing
the synthesis. */
;
else
{
if (current_function_decl == TINST_DECL (p))
if (current_function_decl == p->decl)
/* Avoid redundancy with the "In function" line. */;
else
pp_verbatim (context->printer,
"%s: In instantiation of %qs:\n",
LOCATION_FILE (location),
decl_as_string (TINST_DECL (p),
decl_as_string (p->decl,
TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE));
location = TINST_LOCATION (p);
p = TREE_CHAIN (p);
location = p->locus;
p = p->next;
}
}
......@@ -2421,19 +2422,19 @@ print_instantiation_full_context (diagnostic_context *context)
/* Same as above but less verbose. */
static void
print_instantiation_partial_context (diagnostic_context *context,
tree t, location_t loc)
struct tinst_level *t, location_t loc)
{
expanded_location xloc;
for (; ; t = TREE_CHAIN (t))
for (; ; t = t->next)
{
xloc = expand_location (loc);
if (t == NULL_TREE)
if (t == NULL)
break;
pp_verbatim (context->printer, "%s:%d: instantiated from %qs\n",
xloc.file, xloc.line,
decl_as_string (TINST_DECL (t),
decl_as_string (t->decl,
TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE));
loc = TINST_LOCATION (t);
loc = t->locus;
}
pp_verbatim (context->printer, "%s:%d: instantiated from here",
xloc.file, xloc.line);
......
......@@ -856,11 +856,11 @@ make_aggr_type (enum tree_code code)
bool
in_main_input_context (void)
{
tree tl = outermost_tinst_level();
struct tinst_level *tl = outermost_tinst_level();
if (tl)
return strcmp (main_input_filename,
LOCATION_FILE (TINST_LOCATION (tl))) == 0;
LOCATION_FILE (tl->locus)) == 0;
else
return strcmp (main_input_filename, input_filename) == 0;
}
......@@ -52,12 +52,14 @@ typedef int (*tree_fn_t) (tree, void*);
/* The PENDING_TEMPLATES is a TREE_LIST of templates whose
instantiations have been deferred, either because their definitions
were not yet available, or because we were putting off doing the work.
The TREE_PURPOSE of each entry is either a DECL (for a function or
static data member), or a TYPE (for a class) indicating what we are
hoping to instantiate. The TREE_VALUE is not used. */
static GTY(()) tree pending_templates;
static GTY(()) tree last_pending_template;
were not yet available, or because we were putting off doing the work. */
struct pending_template GTY (()) {
struct pending_template *next;
struct tinst_level *tinst;
};
static GTY(()) struct pending_template *pending_templates;
static GTY(()) struct pending_template *last_pending_template;
int processing_template_parmlist;
static int template_header_count;
......@@ -65,7 +67,7 @@ static int template_header_count;
static GTY(()) tree saved_trees;
static VEC(int,heap) *inline_parm_levels;
static GTY(()) tree current_tinst_level;
static GTY(()) struct tinst_level *current_tinst_level;
static GTY(()) tree saved_access_scope;
......@@ -104,7 +106,7 @@ static int unify (tree, tree, tree, tree, int);
static void add_pending_template (tree);
static int push_tinst_level (tree);
static void pop_tinst_level (void);
static void reopen_tinst_level (tree);
static tree reopen_tinst_level (struct tinst_level *);
static tree tsubst_initializer_list (tree, tree);
static tree get_class_bindings (tree, tree, tree);
static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t,
......@@ -5139,7 +5141,7 @@ add_pending_template (tree d)
tree ti = (TYPE_P (d)
? CLASSTYPE_TEMPLATE_INFO (d)
: DECL_TEMPLATE_INFO (d));
tree pt;
struct pending_template *pt;
int level;
if (TI_PENDING_TEMPLATE_FLAG (ti))
......@@ -5148,14 +5150,16 @@ add_pending_template (tree d)
/* We are called both from instantiate_decl, where we've already had a
tinst_level pushed, and instantiate_template, where we haven't.
Compensate. */
level = !(current_tinst_level && TINST_DECL (current_tinst_level) == d);
level = !current_tinst_level || current_tinst_level->decl != d;
if (level)
push_tinst_level (d);
pt = tree_cons (current_tinst_level, d, NULL_TREE);
pt = GGC_NEW (struct pending_template);
pt->next = NULL;
pt->tinst = current_tinst_level;
if (last_pending_template)
TREE_CHAIN (last_pending_template) = pt;
last_pending_template->next = pt;
else
pending_templates = pt;
......@@ -5974,7 +5978,7 @@ static int last_template_error_tick;
static int
push_tinst_level (tree d)
{
tree new;
struct tinst_level *new;
if (tinst_depth >= max_tinst_depth)
{
......@@ -5994,11 +5998,11 @@ push_tinst_level (tree d)
return 0;
}
new = make_node (TINST_LEVEL);
TINST_DECL (new) = d;
TINST_LOCATION (new) = input_location;
TINST_IN_SYSTEM_HEADER_P (new) = in_system_header;
TREE_CHAIN (new) = current_tinst_level;
new = GGC_NEW (struct tinst_level);
new->decl = d;
new->locus = input_location;
new->in_system_header_p = in_system_header;
new->next = current_tinst_level;
current_tinst_level = new;
++tinst_depth;
......@@ -6017,41 +6021,44 @@ push_tinst_level (tree d)
static void
pop_tinst_level (void)
{
tree old = current_tinst_level;
/* Restore the filename and line number stashed away when we started
this instantiation. */
input_location = TINST_LOCATION (old);
in_system_header = TINST_IN_SYSTEM_HEADER_P (old);
current_tinst_level = TREE_CHAIN (old);
input_location = current_tinst_level->locus;
in_system_header = current_tinst_level->in_system_header_p;
current_tinst_level = current_tinst_level->next;
--tinst_depth;
++tinst_level_tick;
}
/* We're instantiating a deferred template; restore the template
instantiation context in which the instantiation was requested, which
is one step out from LEVEL. */
is one step out from LEVEL. Return the corresponding DECL or TYPE. */
static void
reopen_tinst_level (tree level)
static tree
reopen_tinst_level (struct tinst_level *level)
{
tree t;
struct tinst_level *t;
tinst_depth = 0;
for (t = level; t; t = TREE_CHAIN (t))
for (t = level; t; t = t->next)
++tinst_depth;
current_tinst_level = level;
pop_tinst_level ();
return level->decl;
}
/* Returns the TINST_LEVEL which gives the original instantiation
context. */
tree
struct tinst_level *
outermost_tinst_level (void)
{
return tree_last (current_tinst_level);
struct tinst_level *level = current_tinst_level;
if (level)
while (level->next)
level = level->next;
return level;
}
/* DECL is a friend FUNCTION_DECL or TEMPLATE_DECL. ARGS is the
......@@ -14486,8 +14493,6 @@ out:
void
instantiate_pending_templates (int retries)
{
tree *t;
tree last = NULL_TREE;
int reconsider;
location_t saved_loc = input_location;
int saved_in_system_header = in_system_header;
......@@ -14497,7 +14502,7 @@ instantiate_pending_templates (int retries)
to avoid infinite loop. */
if (pending_templates && retries >= max_tinst_depth)
{
tree decl = TREE_VALUE (pending_templates);
tree decl = pending_templates->tinst->decl;
error ("template instantiation depth exceeds maximum of %d"
" instantiating %q+D, possibly from virtual table generation"
......@@ -14511,14 +14516,13 @@ instantiate_pending_templates (int retries)
do
{
struct pending_template **t = &pending_templates;
struct pending_template *last = NULL;
reconsider = 0;
t = &pending_templates;
while (*t)
{
tree instantiation = TREE_VALUE (*t);
reopen_tinst_level (TREE_PURPOSE (*t));
tree instantiation = reopen_tinst_level ((*t)->tinst);
bool complete = false;
if (TYPE_P (instantiation))
{
......@@ -14539,15 +14543,7 @@ instantiate_pending_templates (int retries)
reconsider = 1;
}
if (COMPLETE_TYPE_P (instantiation))
/* If INSTANTIATION has been instantiated, then we don't
need to consider it again in the future. */
*t = TREE_CHAIN (*t);
else
{
last = *t;
t = &TREE_CHAIN (*t);
}
complete = COMPLETE_TYPE_P (instantiation);
}
else
{
......@@ -14562,19 +14558,21 @@ instantiate_pending_templates (int retries)
reconsider = 1;
}
if (DECL_TEMPLATE_SPECIALIZATION (instantiation)
|| DECL_TEMPLATE_INSTANTIATED (instantiation))
/* If INSTANTIATION has been instantiated, then we don't
need to consider it again in the future. */
*t = TREE_CHAIN (*t);
else
{
last = *t;
t = &TREE_CHAIN (*t);
}
complete = (DECL_TEMPLATE_SPECIALIZATION (instantiation)
|| DECL_TEMPLATE_INSTANTIATED (instantiation));
}
if (complete)
/* If INSTANTIATION has been instantiated, then we don't
need to consider it again in the future. */
*t = (*t)->next;
else
{
last = *t;
t = &(*t)->next;
}
tinst_depth = 0;
current_tinst_level = NULL_TREE;
current_tinst_level = NULL;
}
last_pending_template = last;
}
......@@ -14823,7 +14821,7 @@ record_last_problematic_instantiation (void)
last_template_error_tick = tinst_level_tick;
}
tree
struct tinst_level *
current_instantiation (void)
{
return current_tinst_level;
......
......@@ -2318,11 +2318,6 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
*walk_subtrees_p = 0;
break;
case TINST_LEVEL:
WALK_SUBTREE (TINST_DECL (*tp));
*walk_subtrees_p = 0;
break;
case PTRMEM_CST:
WALK_SUBTREE (TREE_TYPE (*tp));
*walk_subtrees_p = 0;
......
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