diff options
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r-- | gcc/cp/pt.c | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 36f1b00fa6b..eb43271e850 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -15635,6 +15635,27 @@ template_for_substitution (tree decl) return tmpl; } +/* Returns true if we need to instantiate this template instance even if we + know we aren't going to emit it.. */ + +bool +always_instantiate_p (tree decl) +{ + /* We always instantiate inline functions so that we can inline them. An + explicit instantiation declaration prohibits implicit instantiation of + non-inline functions. With high levels of optimization, we would + normally inline non-inline functions -- but we're not allowed to do + that for "extern template" functions. Therefore, we check + DECL_DECLARED_INLINE_P, rather than possibly_inlined_p. */ + return ((TREE_CODE (decl) == FUNCTION_DECL + && DECL_DECLARED_INLINE_P (decl)) + /* And we need to instantiate static data members so that + their initializers are available in integral constant + expressions. */ + || (TREE_CODE (decl) == VAR_DECL + && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))); +} + /* Produce the definition of D, a _DECL generated from a template. If DEFER_OK is nonzero, then we don't have to actually do the instantiation now; we just have to do it sometime. Normally it is @@ -15688,6 +15709,15 @@ instantiate_decl (tree d, int defer_ok, the instantiation. */ return d; + /* Check to see whether we know that this template will be + instantiated in some other file, as with "extern template" + extension. */ + external_p = (DECL_INTERFACE_KNOWN (d) && DECL_REALLY_EXTERN (d)); + + /* In general, we do not instantiate such templates. */ + if (external_p && !always_instantiate_p (d)) + return d; + gen_tmpl = most_general_template (tmpl); gen_args = DECL_TI_ARGS (d); @@ -15781,26 +15811,6 @@ instantiate_decl (tree d, int defer_ok, pop_access_scope (d); } - /* Check to see whether we know that this template will be - instantiated in some other file, as with "extern template" - extension. */ - external_p = (DECL_INTERFACE_KNOWN (d) && DECL_REALLY_EXTERN (d)); - /* In general, we do not instantiate such templates... */ - if (external_p - /* ... but we instantiate inline functions so that we can inline - them. An explicit instantiation declaration prohibits implicit - instantiation of non-inline functions. With high levels of - optimization, we would normally inline non-inline functions - -- but we're not allowed to do that for "extern template" functions. - Therefore, we check DECL_DECLARED_INLINE_P, rather than - possibly_inlined_p. And ... */ - && ! (TREE_CODE (d) == FUNCTION_DECL - && DECL_DECLARED_INLINE_P (d)) - /* ... we instantiate static data members whose values are - needed in integral constant expressions. */ - && ! (TREE_CODE (d) == VAR_DECL - && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (d))) - goto out; /* Defer all other templates, unless we have been explicitly forbidden from doing so. */ if (/* If there is no definition, we cannot instantiate the |