Commit a2033ab1 by Jason Merrill Committed by Jason Merrill

Allow partial specialization of variable templates.

	* cp-tree.h (TINFO_USED_TEMPLATE_ID): New.
	* decl.c (duplicate_decls): Copy it.
	* error.c (dump_decl) [TEMPLATE_ID_EXPR]: Handle variables.
	* parser.c (cp_parser_decltype_expr): Do call finish_id_expression
	on template-ids.
	* pt.c (register_specialization): Remember variable template insts.
	(instantiate_template_1): Find the matching partial specialization.
	(check_explicit_specialization): Allow variable partial specialization.
	(process_partial_specialization): Likewise.
	(push_template_decl_real): Likewise.
	(more_specialized_partial_spec): Rename from more_specialized_class.
	(most_specialized_partial_spec): Rename from most_specialized_class.
	(get_partial_spec_bindings): Rename from get_class_bindings.

From-SVN: r218104
parent d896cc4d
2014-11-26 Jason Merrill <jason@redhat.com>
Allow partial specialization of variable templates.
* cp-tree.h (TINFO_USED_TEMPLATE_ID): New.
* decl.c (duplicate_decls): Copy it.
* error.c (dump_decl) [TEMPLATE_ID_EXPR]: Handle variables.
* parser.c (cp_parser_decltype_expr): Do call finish_id_expression
on template-ids.
* pt.c (register_specialization): Remember variable template insts.
(instantiate_template_1): Find the matching partial specialization.
(check_explicit_specialization): Allow variable partial specialization.
(process_partial_specialization): Likewise.
(push_template_decl_real): Likewise.
(more_specialized_partial_spec): Rename from more_specialized_class.
(most_specialized_partial_spec): Rename from most_specialized_class.
(get_partial_spec_bindings): Rename from get_class_bindings.
2014-11-26 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/63757
......
......@@ -99,6 +99,7 @@ c-common.h, not after.
QUALIFIED_NAME_IS_TEMPLATE (in SCOPE_REF)
DECLTYPE_FOR_INIT_CAPTURE (in DECLTYPE_TYPE)
CONSTRUCTOR_NO_IMPLICIT_ZERO (in CONSTRUCTOR)
TINFO_USED_TEMPLATE_ID (in TEMPLATE_INFO)
2: IDENTIFIER_OPNAME_P (in IDENTIFIER_NODE)
ICS_THIS_FLAG (in _CONV)
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (in VAR_DECL)
......@@ -801,6 +802,12 @@ typedef struct qualified_typedef_usage_s qualified_typedef_usage_t;
#define FNDECL_HAS_ACCESS_ERRORS(NODE) \
(TINFO_HAS_ACCESS_ERRORS (DECL_TEMPLATE_INFO (NODE)))
/* Non-zero if this variable template specialization was specified using a
template-id, so it's a partial or full specialization and not a definition
of the member template of a particular class specialization. */
#define TINFO_USED_TEMPLATE_ID(NODE) \
(TREE_LANG_FLAG_1 (TEMPLATE_INFO_CHECK (NODE)))
struct GTY(()) tree_template_info {
struct tree_common common;
vec<qualified_typedef_usage_t, va_gc> *typedefs_needing_access_checking;
......
......@@ -2137,7 +2137,14 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
DECL_LANG_SPECIFIC (newdecl)->u.min.u2 =
DECL_LANG_SPECIFIC (olddecl)->u.min.u2;
if (DECL_TEMPLATE_INFO (newdecl))
new_template_info = DECL_TEMPLATE_INFO (newdecl);
{
new_template_info = DECL_TEMPLATE_INFO (newdecl);
if (DECL_TEMPLATE_INSTANTIATION (olddecl)
&& DECL_TEMPLATE_SPECIALIZATION (newdecl))
/* Remember the presence of explicit specialization args. */
TINFO_USED_TEMPLATE_ID (DECL_TEMPLATE_INFO (olddecl))
= TINFO_USED_TEMPLATE_ID (new_template_info);
}
DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
}
/* Only functions have these fields. */
......
......@@ -1212,7 +1212,9 @@ dump_decl (cxx_pretty_printer *pp, tree t, int flags)
tree args = TREE_OPERAND (t, 1);
if (is_overloaded_fn (name))
name = DECL_NAME (get_first_fn (name));
name = get_first_fn (name);
if (DECL_P (name))
name = DECL_NAME (name);
dump_decl (pp, name, flags);
pp_cxx_begin_template_argument_list (pp);
if (args == error_mark_node)
......
......@@ -12175,7 +12175,6 @@ cp_parser_decltype_expr (cp_parser *parser,
if (expr
&& expr != error_mark_node
&& TREE_CODE (expr) != TEMPLATE_ID_EXPR
&& TREE_CODE (expr) != TYPE_DECL
&& (TREE_CODE (expr) != BIT_NOT_EXPR
|| !TYPE_P (TREE_OPERAND (expr, 0)))
......
......@@ -13,25 +13,25 @@ struct metatuple<add_pointer> {
};
template<template<class T> class Meta>
struct metatuple<Meta, Meta> { // { dg-error "candidates" }
struct metatuple<Meta, Meta> { // { dg-message "candidates" }
static const int value = 2;
};
template<template<class T> class... Metafunctions>
struct metatuple<add_pointer, Metafunctions...> { // { dg-error "" }
struct metatuple<add_pointer, Metafunctions...> { // { dg-message "" }
static const int value = 3;
};
template<template<class T> class First,
template<class T> class... Metafunctions>
struct metatuple<First, Metafunctions...> { // { dg-error "struct" }
struct metatuple<First, Metafunctions...> { // { dg-message "struct" }
static const int value = 4;
};
template<template<class T> class First,
template<class T> class Second,
template<class T> class... Metafunctions>
struct metatuple<First, Second, Metafunctions...> { // { dg-error "struct" }
struct metatuple<First, Second, Metafunctions...> { // { dg-message "struct" }
static const int value = 5;
};
......
// { dg-do compile { target c++14 } }
template <class T> T t = 42;
template <class T> T* t<T*> = nullptr;
void *p = t<void*>;
// DR 1727: a specialization doesn't need to have the same type
// { dg-do compile { target c++14 } }
template <class T> T t = 42;
template <class T> int t<T*> = 0;
template<class T, class U> struct same;
template<class T> struct same<T,T> {};
same<int,decltype(t<void*>)> s;
// { dg-do compile { target c++14 } }
template <class T> T t1 = 42;
template <class T> T* t1<T> = nullptr; // { dg-error "partial" }
template <class T> T t2 = 42;
template <class T> T* t2<T*> = nullptr;
template <class T> T* t2<T*> = nullptr; // { dg-error "redefinition" }
template <class T, class U> T t3 = U();
template <class T> T t3<T,int> = 42;
template <class U> int t3<int,U> = U();
int i = t3<int,int>; // { dg-error "ambiguous" }
template <class T> T t4 = T();
void *p = t4<void*>;
template <class T> T* t4<T*> = nullptr; // { dg-error "after instantiation" }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment