diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 2 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 2 | ||||
-rw-r--r-- | gcc/cp/optimize.c | 29 | ||||
-rw-r--r-- | gcc/cp/pt.c | 42 |
5 files changed, 48 insertions, 36 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 96c0900..020da6b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,14 @@ 2000-04-05 Mark Mitchell <mark@codesourcery.com> + * cp-tree.h (instantiate_decl): Change prototype. + * decl2.c (mark_used): Adjust call. + * optimize.c (inlinable_function_p): Adjust handling of templates. + * pt.c (do_decl_instantiation): Adjust call to instantiate_decl. + (do_type_instantiation): Likewise. + (instantiate_decl): Defer more templates. + (instantiate_pending_templates): Adjust logic to handle inline + friend functions. + * Makefile.in (GGC_H): New variable. Use it throughout in place of ggc.h. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 07b8675..cbdd486 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4123,7 +4123,7 @@ extern int more_specialized PARAMS ((tree, tree, tree)); extern void mark_class_instantiated PARAMS ((tree, int)); extern void do_decl_instantiation PARAMS ((tree, tree, tree)); extern void do_type_instantiation PARAMS ((tree, tree)); -extern tree instantiate_decl PARAMS ((tree)); +extern tree instantiate_decl PARAMS ((tree, int)); extern tree get_bindings PARAMS ((tree, tree, tree)); extern void add_tree PARAMS ((tree)); extern void add_maybe_template PARAMS ((tree, tree)); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index f6d5b78..982bd2d 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -5237,7 +5237,7 @@ mark_used (decl) && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl) && (!DECL_EXPLICIT_INSTANTIATION (decl) || (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl)))) - instantiate_decl (decl); + instantiate_decl (decl, /*defer_ok=*/1); } /* Helper function for named_class_head_sans_basetype nonterminal. We diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c index 5ba9ea7..63ec81a 100644 --- a/gcc/cp/optimize.c +++ b/gcc/cp/optimize.c @@ -463,10 +463,6 @@ inlinable_function_p (fn, id) it. */ else if (!DECL_INLINE (fn)) ; - /* If we don't have the function body available, we can't inline - it. */ - else if (!DECL_SAVED_TREE (fn)) - ; /* We can't inline varargs functions. */ else if (varargs_function_p (fn)) ; @@ -481,6 +477,21 @@ inlinable_function_p (fn, id) /* Squirrel away the result so that we don't have to check again. */ DECL_UNINLINABLE (fn) = !inlinable; + /* We can inline a template instantiation only if it's fully + instantiated. */ + if (inlinable + && DECL_TEMPLATE_INFO (fn) + && TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn))) + { + fn = instantiate_decl (fn, /*defer_ok=*/0); + inlinable = !TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn)); + } + + /* If we don't have the function body available, we can't inline + it. */ + if (!DECL_SAVED_TREE (fn)) + inlinable = 0; + /* Don't do recursive inlining, either. We don't record this in DECL_UNLINABLE; we may be able to inline this function later. */ if (inlinable) @@ -492,16 +503,6 @@ inlinable_function_p (fn, id) inlinable = 0; } - /* We can inline a template instantiation only if it's fully - instantiated. */ - if (inlinable - && DECL_TEMPLATE_INFO (fn) - && TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn))) - { - fn = instantiate_decl (fn); - inlinable = !TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn)); - } - /* Return the result. */ return inlinable; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 83d738d..2323993 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -9129,7 +9129,7 @@ do_decl_instantiation (declspecs, declarator, storage) mark_decl_instantiated (result, extern_p); repo_template_instantiated (result, extern_p); if (! extern_p) - instantiate_decl (result); + instantiate_decl (result, /*defer_ok=*/1); } void @@ -9265,7 +9265,7 @@ do_type_instantiation (t, storage) mark_decl_instantiated (tmp, extern_p); repo_template_instantiated (tmp, extern_p); if (! extern_p) - instantiate_decl (tmp); + instantiate_decl (tmp, /*defer_ok=*/1); } for (tmp = TYPE_FIELDS (t); tmp; tmp = TREE_CHAIN (tmp)) @@ -9274,7 +9274,7 @@ do_type_instantiation (t, storage) mark_decl_instantiated (tmp, extern_p); repo_template_instantiated (tmp, extern_p); if (! extern_p) - instantiate_decl (tmp); + instantiate_decl (tmp, /*defer_ok=*/1); } for (tmp = CLASSTYPE_TAGS (t); tmp; tmp = TREE_CHAIN (tmp)) @@ -9376,11 +9376,14 @@ regenerate_decl_from_template (decl, tmpl) register_specialization (decl, gen_tmpl, args); } -/* Produce the definition of D, a _DECL generated from a template. */ +/* Produce the definition of D, a _DECL generated from a template. If + DEFER_OK is non-zero, then we don't have to actually do the + instantiation now; we just have to do it sometime. */ tree -instantiate_decl (d) +instantiate_decl (d, defer_ok) tree d; + int defer_ok; { tree tmpl = DECL_TI_TEMPLATE (d); tree args = DECL_TI_ARGS (d); @@ -9513,20 +9516,18 @@ instantiate_decl (d) && ! (TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (d))) goto out; + /* We need to set up DECL_INITIAL regardless of pattern_defined if + the variable is a static const initialized in the class body. */ if (TREE_CODE (d) == VAR_DECL && TREE_READONLY (d) && 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 && 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. */ + ; + /* Defer all other templates, unless we have been explicitly + forbidden from doing so. We restore the source position here + because it's used by add_pending_template. */ + else if (! pattern_defined || defer_ok) + { lineno = line; input_filename = file; @@ -9657,7 +9658,7 @@ instantiate_pending_templates () fn; fn = TREE_CHAIN (fn)) if (! DECL_ARTIFICIAL (fn)) - instantiate_decl (fn); + instantiate_decl (fn, /*defer_ok=*/0); if (COMPLETE_TYPE_P (instantiation)) { instantiated_something = 1; @@ -9674,10 +9675,11 @@ instantiate_pending_templates () } else { - if (DECL_TEMPLATE_INSTANTIATION (instantiation) + if (!DECL_TEMPLATE_SPECIALIZATION (instantiation) && !DECL_TEMPLATE_INSTANTIATED (instantiation)) { - instantiation = instantiate_decl (instantiation); + instantiation = instantiate_decl (instantiation, + /*defer_ok=*/0); if (DECL_TEMPLATE_INSTANTIATED (instantiation)) { instantiated_something = 1; @@ -9685,7 +9687,7 @@ instantiate_pending_templates () } } - if (!DECL_TEMPLATE_INSTANTIATION (instantiation) + 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. */ @@ -9717,7 +9719,7 @@ instantiate_pending_templates () template = TREE_PURPOSE (*t); args = get_bindings (template, fn, NULL_TREE); fn = instantiate_template (template, args); - instantiate_decl (fn); + instantiate_decl (fn, /*defer_ok=*/0); reconsider = 1; } |