diff options
author | Mark Mitchell <mmitchel@gcc.gnu.org> | 2005-09-03 18:27:39 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2005-09-03 18:27:39 +0000 |
commit | f7e4e4847c4b252bb232191d28c05439e7c85612 (patch) | |
tree | 462c8d93c505a7da70361030d09b9e124b3fb9b3 /gcc | |
parent | 2725073463dfe4d70a5111f6723a2f4ea36ba875 (diff) | |
download | gcc-f7e4e4847c4b252bb232191d28c05439e7c85612.zip gcc-f7e4e4847c4b252bb232191d28c05439e7c85612.tar.gz gcc-f7e4e4847c4b252bb232191d28c05439e7c85612.tar.bz2 |
re PR c++/23699 (rejects static int as non constant after "extern template")
PR c++/23699
* decl2.c (mark_used): Always instantiate static data members
initialized by constant expressions.
* pt.c (instantiate_decl): Instantiate the initializers for static
data members initialized by constant expressions.
From-SVN: r103807
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/pt.c | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 773d865..b159077 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -11371,6 +11371,7 @@ instantiate_decl (tree d, int defer_ok, bool pattern_defined; int need_push; location_t saved_loc = input_location; + bool external_p; /* This function should only be used to instantiate templates for functions and static member variables. */ @@ -11488,17 +11489,32 @@ instantiate_decl (tree d, int defer_ok, pop_access_scope (d); } - /* Do not instantiate templates that we know will be defined - elsewhere. */ - if (DECL_INTERFACE_KNOWN (d) - && DECL_REALLY_EXTERN (d) - && ! (TREE_CODE (d) == FUNCTION_DECL - && DECL_INLINE (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 and ... */ + && ! (TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (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. We restore the source position here - because it's used by add_pending_template. */ - else if (! pattern_defined || defer_ok) + forbidden from doing so. */ + if (/* If there is no definition, we cannot instantiate the + template. */ + ! pattern_defined + /* If it's OK to postpone instantiation, do so. */ + || defer_ok + /* If this is a static data member that will be defined + elsewhere, we don't want to instantiate the entire data + member, but we do want to instantiate the initializer so that + we can substitute that elsewhere. */ + || (external_p && TREE_CODE (d) == VAR_DECL)) { /* The definition of the static data member is now required so we must substitute the initializer. */ @@ -11514,6 +11530,8 @@ instantiate_decl (tree d, int defer_ok, pop_nested_class (); } + /* We restore the source position here because it's used by + add_pending_template. */ input_location = saved_loc; if (at_eof && !pattern_defined @@ -11528,7 +11546,10 @@ instantiate_decl (tree d, int defer_ok, pedwarn ("explicit instantiation of %qD but no definition available", d); - add_pending_template (d); + /* ??? Historically, we have instantiated inline functions, even + when marked as "extern template". */ + if (!(external_p && TREE_CODE (d) == VAR_DECL)) + add_pending_template (d); goto out; } /* Tell the repository that D is available in this translation unit |