aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@casey.soma.redhat.com>2000-06-06 00:12:40 +0000
committerJason Merrill <jason@gcc.gnu.org>2000-06-05 20:12:40 -0400
commit3ae18eaf85fbb012583730c8312aca6286b6275f (patch)
treec13a7bead4572d9b4e30158249769ecc0ba47404 /gcc/cp
parentef0b4ef8d64f6a2ec333acbfc2ae9fcb207d51a0 (diff)
downloadgcc-3ae18eaf85fbb012583730c8312aca6286b6275f.zip
gcc-3ae18eaf85fbb012583730c8312aca6286b6275f.tar.gz
gcc-3ae18eaf85fbb012583730c8312aca6286b6275f.tar.bz2
search.c (maybe_suppress_debug_info): Don't check CLASSTYPE_INTERFACE_ONLY if CLASSTYPE_INTERFACE_KNOWN isn't set.
* search.c (maybe_suppress_debug_info): Don't check CLASSTYPE_INTERFACE_ONLY if CLASSTYPE_INTERFACE_KNOWN isn't set. * pt.c (mark_decl_instantiated): Do SET_DECL_EXPLICIT_INSTANTIATION here if extern_p. Remember instantiation context in deferred instantiations. * cp-tree.h (struct tinst_level): Remove. (TINST_DECL, TINST_LINE, TINST_FILE): New macros. * pt.c (current_tinst_level): Now a tree. (print_template_context, push_tinst_level, pop_tinst_level, tinst_for_decl): Adjust. (reopen_tinst_level): New fn. (init_pt): Register current_tinst_level as a root. (add_pending_template): Put current_tinst_level in TREE_PURPOSE of the pending templates list. (instantiate_pending_templates): Adjust. Call reopen_tinst_level. * lex.c (extract_interface_info): Adjust. * decl2.c (warn_if_unknown_interface): Adjust. From-SVN: r34415
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog22
-rw-r--r--gcc/cp/cp-tree.h17
-rw-r--r--gcc/cp/decl2.c6
-rw-r--r--gcc/cp/lex.c4
-rw-r--r--gcc/cp/pt.c121
-rw-r--r--gcc/cp/search.c10
6 files changed, 120 insertions, 60 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f0f7e367..949f4c8 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,25 @@
+2000-06-05 Jason Merrill <jason@casey.soma.redhat.com>
+
+ * search.c (maybe_suppress_debug_info): Don't check
+ CLASSTYPE_INTERFACE_ONLY if CLASSTYPE_INTERFACE_KNOWN isn't set.
+
+ * pt.c (mark_decl_instantiated): Do SET_DECL_EXPLICIT_INSTANTIATION
+ here if extern_p.
+
+ Remember instantiation context in deferred instantiations.
+ * cp-tree.h (struct tinst_level): Remove.
+ (TINST_DECL, TINST_LINE, TINST_FILE): New macros.
+ * pt.c (current_tinst_level): Now a tree.
+ (print_template_context, push_tinst_level, pop_tinst_level,
+ tinst_for_decl): Adjust.
+ (reopen_tinst_level): New fn.
+ (init_pt): Register current_tinst_level as a root.
+ (add_pending_template): Put current_tinst_level in TREE_PURPOSE
+ of the pending templates list.
+ (instantiate_pending_templates): Adjust. Call reopen_tinst_level.
+ * lex.c (extract_interface_info): Adjust.
+ * decl2.c (warn_if_unknown_interface): Adjust.
+
2000-06-05 Mark Mitchell <mark@codesourcery.com>
* class.c (indirect_primary_base_p): New function.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index fa03358..1b65b6a 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3392,15 +3392,12 @@ typedef enum unification_kind_t {
DEDUCE_EXACT
} unification_kind_t;
-/* The template currently being instantiated, and where the instantiation
- was triggered. */
-struct tinst_level
-{
- tree decl;
- int line;
- const char *file;
- struct tinst_level *next;
-};
+/* Macros for operating on a template instantation level node, represented
+ by an EXPR_WITH_FILE_LOCATION. */
+
+#define TINST_DECL(NODE) EXPR_WFL_NODE (NODE)
+#define TINST_LINE(NODE) EXPR_WFL_LINENO (NODE)
+#define TINST_FILE(NODE) EXPR_WFL_FILENAME (NODE)
extern void maybe_print_template_context PARAMS ((void));
@@ -4349,7 +4346,7 @@ extern tree instantiate_class_template PARAMS ((tree));
extern tree instantiate_template PARAMS ((tree, tree));
extern void overload_template_name PARAMS ((tree));
extern int fn_type_unification PARAMS ((tree, tree, tree, tree, tree, unification_kind_t));
-struct tinst_level *tinst_for_decl PARAMS ((void));
+extern tree tinst_for_decl PARAMS ((void));
extern void mark_decl_instantiated PARAMS ((tree, int));
extern int more_specialized PARAMS ((tree, tree, tree));
extern void mark_class_instantiated PARAMS ((tree, int));
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 95702d6..f132478 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -911,14 +911,14 @@ warn_if_unknown_interface (decl)
if (flag_alt_external_templates)
{
- struct tinst_level *til = tinst_for_decl ();
+ tree til = tinst_for_decl ();
int sl = lineno;
const char *sf = input_filename;
if (til)
{
- lineno = til->line;
- input_filename = til->file;
+ lineno = TINST_LINE (til);
+ input_filename = TINST_FILE (til);
}
cp_warning ("template `%#D' instantiated in file without #pragma interface",
decl);
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 5c09fef..839f34f 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -933,10 +933,10 @@ extract_interface_info ()
if (flag_alt_external_templates)
{
- struct tinst_level *til = tinst_for_decl ();
+ tree til = tinst_for_decl ();
if (til)
- fileinfo = get_time_identifier (til->file);
+ fileinfo = get_time_identifier (TINST_FILE (til));
}
if (!fileinfo)
fileinfo = get_time_identifier (input_filename);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 48df27f..9908c54 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -71,6 +71,8 @@ static tree saved_trees;
static varray_type inline_parm_levels;
static size_t inline_parm_levels_used;
+tree current_tinst_level;
+
/* A map from local variable declarations in the body of the template
presently being instantiated to the corresponding instantiated
local variables. */
@@ -98,6 +100,7 @@ static int try_one_overload PARAMS ((tree, tree, tree, tree, tree,
static int unify PARAMS ((tree, tree, tree, tree, int));
static void add_pending_template PARAMS ((tree));
static int push_tinst_level PARAMS ((tree));
+static void reopen_tinst_level PARAMS ((tree));
static tree classtype_mangled_name PARAMS ((tree));
static char *mangle_class_name_for_template PARAMS ((char *, tree, tree));
static tree tsubst_expr_values PARAMS ((tree, tree));
@@ -172,6 +175,7 @@ init_pt ()
ggc_add_tree_root (&pending_templates, 1);
ggc_add_tree_root (&maybe_templates, 1);
ggc_add_tree_root (&saved_trees, 1);
+ ggc_add_tree_root (&current_tinst_level, 1);
}
/* Do any processing required when DECL (a member template declaration
@@ -3619,14 +3623,28 @@ static void
add_pending_template (d)
tree d;
{
- tree ti = (TYPE_P (d)) ? CLASSTYPE_TEMPLATE_INFO (d) : DECL_TEMPLATE_INFO (d);
+ tree ti = (TYPE_P (d)
+ ? CLASSTYPE_TEMPLATE_INFO (d)
+ : DECL_TEMPLATE_INFO (d));
+ int level;
if (TI_PENDING_TEMPLATE_FLAG (ti))
return;
- *template_tail = tree_cons (build_srcloc_here (), d, NULL_TREE);
+ /* 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);
+
+ if (level)
+ push_tinst_level (d);
+
+ *template_tail = tree_cons (current_tinst_level, d, NULL_TREE);
template_tail = &TREE_CHAIN (*template_tail);
TI_PENDING_TEMPLATE_FLAG (ti) = 1;
+
+ if (level)
+ pop_tinst_level ();
}
@@ -4268,8 +4286,6 @@ uses_template_parms (t)
return for_each_template_parm (t, 0, 0);
}
-static struct tinst_level *current_tinst_level;
-static struct tinst_level *free_tinst_level;
static int tinst_depth;
extern int max_tinst_depth;
#ifdef GATHER_STATISTICS
@@ -4286,38 +4302,40 @@ static void
print_template_context (err)
int err;
{
- struct tinst_level *p = current_tinst_level;
+ tree p = current_tinst_level;
int line = lineno;
const char *file = input_filename;
if (err && p)
{
- if (current_function_decl != p->decl
+ if (current_function_decl != TINST_DECL (p)
&& current_function_decl != NULL_TREE)
/* We can get here during the processing of some synthesized
- method. Then, p->decl will be the function that's causing
+ method. Then, TINST_DECL (p) will be the function that's causing
the synthesis. */
;
else
{
- if (current_function_decl == p->decl)
+ if (current_function_decl == TINST_DECL (p))
/* Avoid redundancy with the the "In function" line. */;
else
fprintf (stderr, "%s: In instantiation of `%s':\n",
- file, decl_as_string (p->decl, TS_DECL_TYPE | TS_FUNC_NORETURN));
+ file, decl_as_string (TINST_DECL (p),
+ TS_DECL_TYPE | TS_FUNC_NORETURN));
- line = p->line;
- file = p->file;
- p = p->next;
+ line = TINST_LINE (p);
+ file = TINST_FILE (p);
+ p = TREE_CHAIN (p);
}
}
- for (; p; p = p->next)
+ for (; p; p = TREE_CHAIN (p))
{
fprintf (stderr, "%s:%d: instantiated from `%s'\n", file, line,
- decl_as_string (p->decl, TS_DECL_TYPE | TS_FUNC_NORETURN));
- line = p->line;
- file = p->file;
+ decl_as_string (TINST_DECL (p),
+ TS_DECL_TYPE | TS_FUNC_NORETURN));
+ line = TINST_LINE (p);
+ file = TINST_FILE (p);
}
fprintf (stderr, "%s:%d: instantiated from here\n", file, line);
}
@@ -4335,11 +4353,14 @@ maybe_print_template_context ()
print_template_context (1);
}
+/* We're starting to instantiate D; record the template instantiation context
+ for diagnostics and to restore it later. */
+
static int
push_tinst_level (d)
tree d;
{
- struct tinst_level *new;
+ tree new;
if (tinst_depth >= max_tinst_depth)
{
@@ -4358,18 +4379,8 @@ push_tinst_level (d)
return 0;
}
- if (free_tinst_level)
- {
- new = free_tinst_level;
- free_tinst_level = new->next;
- }
- else
- new = (struct tinst_level *) xmalloc (sizeof (struct tinst_level));
-
- new->decl = d;
- new->line = lineno;
- new->file = input_filename;
- new->next = current_tinst_level;
+ new = build_expr_wfl (d, input_filename, lineno, 0);
+ TREE_CHAIN (new) = current_tinst_level;
current_tinst_level = new;
++tinst_depth;
@@ -4382,31 +4393,53 @@ push_tinst_level (d)
return 1;
}
+/* We're done instantiating this template; return to the instantiation
+ context. */
+
void
pop_tinst_level ()
{
- struct tinst_level *old = current_tinst_level;
+ tree old = current_tinst_level;
/* Restore the filename and line number stashed away when we started
this instantiation. */
- lineno = old->line;
- input_filename = old->file;
+ lineno = TINST_LINE (old);
+ input_filename = TINST_FILE (old);
extract_interface_info ();
- current_tinst_level = old->next;
- old->next = free_tinst_level;
- free_tinst_level = old;
+ current_tinst_level = TREE_CHAIN (old);
--tinst_depth;
++tinst_level_tick;
}
-struct tinst_level *
+/* We're instantiating a deferred template; restore the template
+ instantiation context in which the instantiation was requested, which
+ is one step out from LEVEL. */
+
+static void
+reopen_tinst_level (level)
+ tree level;
+{
+ tree t;
+
+ tinst_depth = 0;
+ for (t = level; t; t = TREE_CHAIN (t))
+ ++tinst_depth;
+
+ current_tinst_level = level;
+ pop_tinst_level ();
+}
+
+/* Return the outermost template instantiation context, for use with
+ -falt-external-templates. */
+
+tree
tinst_for_decl ()
{
- struct tinst_level *p = current_tinst_level;
+ tree p = current_tinst_level;
if (p)
- for (; p->next ; p = p->next )
+ for (; TREE_CHAIN (p) ; p = TREE_CHAIN (p))
;
return p;
}
@@ -8761,6 +8794,14 @@ mark_decl_instantiated (result, extern_p)
set correctly by tsubst. */
TREE_PUBLIC (result) = 1;
+ /* We used to set this unconditionally; we moved that to
+ do_decl_instantiation so it wouldn't get set on members of
+ explicit class template instantiations. But we still need to set
+ it here for the 'extern template' case in order to suppress
+ implicit instantiations. */
+ if (extern_p)
+ SET_DECL_EXPLICIT_INSTANTIATION (result);
+
if (! extern_p)
{
DECL_INTERFACE_KNOWN (result) = 1;
@@ -9753,11 +9794,9 @@ instantiate_pending_templates ()
t = &pending_templates;
while (*t)
{
- tree srcloc = TREE_PURPOSE (*t);
tree instantiation = TREE_VALUE (*t);
- input_filename = SRCLOC_FILE (srcloc);
- lineno = SRCLOC_LINE (srcloc);
+ reopen_tinst_level (TREE_PURPOSE (*t));
if (TYPE_P (instantiation))
{
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 1160cd4..efb8e6a 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -2945,10 +2945,12 @@ maybe_suppress_debug_info (t)
/* If we already know how we're handling this class, handle debug info
the same way. */
- if (CLASSTYPE_INTERFACE_ONLY (t))
- TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
- else if (CLASSTYPE_INTERFACE_KNOWN (t))
- /* Don't set it. */;
+ if (CLASSTYPE_INTERFACE_KNOWN (t))
+ {
+ if (CLASSTYPE_INTERFACE_ONLY (t))
+ TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
+ /* else don't set it. */
+ }
/* If the class has a vtable, write out the debug info along with
the vtable. */
else if (TYPE_CONTAINS_VPTR_P (t))