diff options
author | Jason Merrill <jason@casey.soma.redhat.com> | 2000-06-06 00:12:40 +0000 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2000-06-05 20:12:40 -0400 |
commit | 3ae18eaf85fbb012583730c8312aca6286b6275f (patch) | |
tree | c13a7bead4572d9b4e30158249769ecc0ba47404 /gcc/cp | |
parent | ef0b4ef8d64f6a2ec333acbfc2ae9fcb207d51a0 (diff) | |
download | gcc-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/ChangeLog | 22 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 17 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 6 | ||||
-rw-r--r-- | gcc/cp/lex.c | 4 | ||||
-rw-r--r-- | gcc/cp/pt.c | 121 | ||||
-rw-r--r-- | gcc/cp/search.c | 10 |
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 (¤t_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)) |