diff mbox

[var-template] Accept variable template declaration

Message ID 87ip49et6x.fsf@euclid.axiomatics.org
State New
Headers show

Commit Message

Gabriel Dos Reis March 29, 2013, 10:29 p.m. UTC
This patch lets us accept declarations of constexpr variable templates.
Actual semantics processing of specialization is subject of follow up
patches. 

The patch represents a variable template as a variable temploid whose
scope is a namespace, or member template that generates a static data member.

Applied to var-template branch.

-- Gaby

2013-03-29  Gabriel Dos Reis  <gdr@integrable-solutions.net>
 
	* cp-tree.h (variable_template_p): New.
	* pt.c (check_template_variable): Accept variable temploids at
	non-class scope.
	(push_template_decl_real): The current instantiation of a template
	can be a VAR_DECL.

Comments

Jason Merrill March 30, 2013, 12:58 a.m. UTC | #1
On 03/29/2013 06:29 PM, Gabriel Dos Reis wrote:
> +  if (TREE_CODE (t) != TEMPLATE_DECL
> +      || !(DECL_NAMESPACE_SCOPE_P (t) || DECL_MEMBER_TEMPLATE_P (t)))

Why check the scope?

> -  if (!TYPE_P (ctx) || !CLASSTYPE_TEMPLATE_INFO (ctx))
> -    permerror (DECL_SOURCE_LOCATION (decl),
> -	       "%qD is not a static data member of a class template", decl);
> +  if (!TYPE_P (ctx) || !CLASSTYPE_TEMPLATE_INFO (ctx)) {
> +    if (cxx_dialect < cxx1y)
> +      permerror (DECL_SOURCE_LOCATION (decl),
> +                 "%qD is not a static data member of a class template", decl);
> +  }
>    else if (template_header_count > wanted)

I think we still want to check for excess template headers.

> +      else if (VAR_P (decl)) {
> +        if (!DECL_DECLARED_CONSTEXPR_P (decl))
> +          error ("template declaration of non-constexpr variable %qD", decl);
> +      }

Open brace should be on a line by itself.

Jason
diff mbox

Patch

Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 197248)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -4926,6 +4926,18 @@ 
   return TREE_TYPE (type_of_this_parm (fntype));
 }
 
+/* True if T designates a variable template declaration.  */
+inline bool
+variable_template_p (tree t)
+{
+  if (TREE_CODE (t) != TEMPLATE_DECL
+      || !(DECL_NAMESPACE_SCOPE_P (t) || DECL_MEMBER_TEMPLATE_P (t)))
+    return false;
+  if (tree r = DECL_TEMPLATE_RESULT (t))
+    return VAR_P (r);
+  return false;
+}
+
 /* A parameter list indicating for a function with no parameters,
    e.g  "int f(void)".  */
 extern cp_parameter_declarator *no_parameters;
Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c	(revision 197248)
+++ gcc/cp/pt.c	(working copy)
@@ -2270,9 +2270,11 @@ 
 {
   tree ctx = CP_DECL_CONTEXT (decl);
   int wanted = num_template_headers_for_class (ctx);
-  if (!TYPE_P (ctx) || !CLASSTYPE_TEMPLATE_INFO (ctx))
-    permerror (DECL_SOURCE_LOCATION (decl),
-	       "%qD is not a static data member of a class template", decl);
+  if (!TYPE_P (ctx) || !CLASSTYPE_TEMPLATE_INFO (ctx)) {
+    if (cxx_dialect < cxx1y)
+      permerror (DECL_SOURCE_LOCATION (decl),
+                 "%qD is not a static data member of a class template", decl);
+  }
   else if (template_header_count > wanted)
     {
       pedwarn (DECL_SOURCE_LOCATION (decl), 0,
@@ -4616,6 +4618,10 @@ 
 	       && TYPE_DECL_ALIAS_P (decl))
 	/* alias-declaration */
 	gcc_assert (!DECL_ARTIFICIAL (decl));
+      else if (VAR_P (decl)) {
+        if (!DECL_DECLARED_CONSTEXPR_P (decl))
+          error ("template declaration of non-constexpr variable %qD", decl);
+      }
       else
 	{
 	  error ("template declaration of %q#D", decl);