* decl2.c (comdat_linkage): Don't set DECL_DEFER_OUTPUT.
* pt.c (instantiate_decl): Defer comdat templates that might not be
needed.
* cp-tree.h (DECL_NEEDED_P): Also true if !DECL_COMDAT.
* decl2.c (finish_vtable_vardecl): Don't check !DECL_COMDAT.
(finish_file): Likewise.
From-SVN: r31269
2000-01-06 Jason Merrill <jason@casey.cygnus.com>
+ * decl2.c (comdat_linkage): Don't set DECL_DEFER_OUTPUT.
+ * pt.c (instantiate_decl): Defer comdat templates that might not be
+ needed.
+
+ * cp-tree.h (DECL_NEEDED_P): Also true if !DECL_COMDAT.
+ * decl2.c (finish_vtable_vardecl): Don't check !DECL_COMDAT.
+ (finish_file): Likewise.
+
+ * decl2.c (import_export_class): Undo 12/14 change.
+
* error.c (dump_decl): operator new, not operatornew.
* class.c (field_decl_cmp): A nontype is "greater" than a type.
the symbol has been referenced in the generated code. If, however,
we are not generating code, then it is also true when a symbol has
just been used somewhere, even if it's not really needed. */
-#define DECL_NEEDED_P(DECL) \
- ((TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME ((DECL)))) \
+#define DECL_NEEDED_P(DECL) \
+ (! DECL_COMDAT (DECL) \
+ || (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME ((DECL)))) \
|| (flag_syntax_only && TREE_USED ((DECL))))
/* An un-parsed default argument looks like an identifier. */
if (DECL_LANG_SPECIFIC (decl))
DECL_COMDAT (decl) = 1;
-
- if (TREE_CODE (decl) == FUNCTION_DECL)
- DECL_DEFER_OUTPUT (decl) = 1;
}
/* For win32 we also want to put explicit instantiations in
#ifdef VALID_MACHINE_TYPE_ATTRIBUTE
/* FIXME this should really use some sort of target-independent macro. */
if (lookup_attribute ("dllimport", TYPE_ATTRIBUTES (ctype)))
- /* Use -2 so we survive the MULTIPLE_SYMBOL_SPACES check below. */
- import_export = -2;
+ import_export = -1;
else if (lookup_attribute ("dllexport", TYPE_ATTRIBUTES (ctype)))
- import_export = 2;
+ import_export = 1;
#endif
/* If we got -fno-implicit-templates, we import template classes that
import_export_vtable (vars, ctype, 1);
if (! DECL_EXTERNAL (vars)
- && (DECL_INTERFACE_KNOWN (vars)
- || DECL_NEEDED_P (vars)
+ && (DECL_NEEDED_P (vars)
|| (hack_decl_function_context (vars) && TREE_USED (vars)))
&& ! TREE_ASM_WRITTEN (vars))
{
if (DECL_NOT_REALLY_EXTERN (decl)
&& DECL_INITIAL (decl)
- && (DECL_NEEDED_P (decl) || !DECL_COMDAT (decl)))
+ && DECL_NEEDED_P (decl))
DECL_EXTERNAL (decl) = 0;
/* If we're going to need to write this function out, and
(There might be no body if this is a method we haven't
gotten around to synthesizing yet.) */
if (!DECL_EXTERNAL (decl)
- && (DECL_NEEDED_P (decl) || !DECL_COMDAT (decl))
+ && DECL_NEEDED_P (decl)
&& DECL_SAVED_TREE (decl)
&& !DECL_SAVED_INSNS (decl)
&& !TREE_ASM_WRITTEN (decl))
int pattern_defined;
int line = lineno;
char *file = input_filename;
+ tree old_fn = current_function_decl;
/* This function should only be used to instantiate templates for
functions and static member variables. */
&& DECL_INITIAL (d) == NULL_TREE
&& DECL_INITIAL (code_pattern) != NULL_TREE)
/* We need to set up DECL_INITIAL regardless of pattern_defined if
- the variable is a static const initialized in the class body. */;
- else if (! pattern_defined
- || (! (TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (d) && nested)
- && ! at_eof))
- {
- /* Defer all templates except inline functions used in another
- function. We restore the source position here because it's used
- by add_pending_template. */
+ the variable is a static const initialized in the class body. */;
+ else if (pattern_defined && nested
+ && TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (d))
+ /* An inline function used in another function; instantiate it now so
+ we can inline it. */;
+ else if (! pattern_defined || ! at_eof)
+ {
+ /* Defer all other templates. We restore the source position
+ here because it's used by add_pending_template. */
lineno = line;
input_filename = file;
goto out;
}
+ /* If this instantiation is COMDAT, we don't know whether or not we
+ will really need to write it out. If we can't be sure, mark it
+ DECL_DEFER_OUTPUT. NOTE: This increases memory consumption,
+ since we keep some instantiations in memory rather than write
+ them out immediately and forget them. A better approach would be
+ to wait until we know we need them to do the instantiation, but
+ that would break templates with static locals, because we
+ generate the functions to destroy statics before we determine
+ which functions are needed. A better solution would be to
+ generate the ctor and dtor functions as we go. */
+
+ if (TREE_CODE (d) == FUNCTION_DECL
+ && DECL_COMDAT (d)
+ && ! DECL_NEEDED_P (d)
+ /* If the function that caused us to be instantiated is needed, we
+ will be needed, too. */
+ && (! nested || ! DECL_NEEDED_P (old_fn)))
+ DECL_DEFER_OUTPUT (d) = 1;
+
/* We're now committed to instantiating this template. Mark it as
instantiated so that recursive calls to instantiate_decl do not
try to instantiate it again. */