mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-10 05:50:28 +08:00
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
This commit is contained in:
parent
2725073463
commit
f7e4e4847c
41
gcc/cp/pt.c
41
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user