aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mmitchel@gcc.gnu.org>2005-09-03 18:27:39 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2005-09-03 18:27:39 +0000
commitf7e4e4847c4b252bb232191d28c05439e7c85612 (patch)
tree462c8d93c505a7da70361030d09b9e124b3fb9b3 /gcc
parent2725073463dfe4d70a5111f6723a2f4ea36ba875 (diff)
downloadgcc-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.c41
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