diff mbox

[c++-concepts] Allow function parameters to be referenced in trailing requires clauses

Message ID CANq5SyuqTH1v3D3G1Qi0-xUfUmdGChmMkqoX2BbQFHikVCTS4g@mail.gmail.com
State New
Headers show

Commit Message

Andrew Sutton July 30, 2014, 11:49 a.m. UTC
Applied an updated version of this patch.

2014-7-30  Braden Obrzut  <admin@maniacsvault.net>
        * gcc/cp/parser.c (cp_parser_trailing_requirements): Handle requires
        keyword manually so that we can push function parameters back into
        scope.
        * gcc/cp/decl.c (push_function_parms): New. Recovers and reopens
        function parameter scope from declarator.
        * gcc/testsuite/g++.dg/concepts/req*.C: New tests.

2014-07-30  Andrew Sutton  <andrew.n.sutton@gmail.com>
        * gcc/testsuite/g++.dg/concepts/test.C: Removed.

Andrew Sutton


On Tue, Jun 17, 2014 at 5:06 AM, Braden Obrzut <admin@maniacsvault.net> wrote:
> This patch allows function parameters to be referenced by trailing requires
> clauses.  Typically this is used to refer to the type of an implicitly
> generated template.  For example, the following should now be valid (where C
> is some previously defined concept):
>
> auto f1 (auto x) requires C<decltype(x)> ();
>
> Note that the test case trailing-requires-overload.C will fail to compile
> unless the previously submitted patch is applied first.
>
> 2014-06-17  Braden Obrzut  <admin@maniacsvault.net>
>     * gcc/cp/parser.c (cp_parser_trailing_requirements): Handle requires
>     keyword manually so that we can push function parameters back into
>     scope.
>     * gcc/cp/decl.c (push_function_parms): New. Recovers and reopens
>     function parameter scope from declarator.
>     * gcc/testsuite/g++.dg/concepts/trailing-requires.C: New tests.
>     * gcc/testsuite/g++.dg/concepts/trailing-requires-overload.C: New tests.
diff mbox

Patch

Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 212456)
+++ gcc/cp/parser.c	(working copy)
@@ -16982,14 +16982,22 @@  struct cp_manage_requirements {
 static tree
 cp_parser_trailing_requirements (cp_parser *parser, cp_declarator *decl) 
 {
-  // A function declaration may have a trailing requires-clause.
   if (function_declarator_p (decl))
-    if (tree reqs = cp_parser_requires_clause_opt (parser))
-      current_template_reqs = save_trailing_requirements (reqs);
+    {
+      if (cp_lexer_next_token_is_keyword (parser->lexer, RID_REQUIRES))
+        {
+          ++cp_unevaluated_operand;
+          push_function_parms (decl);
+          cp_lexer_consume_token (parser->lexer);
+          tree reqs = cp_parser_requires_clause (parser);
+          current_template_reqs = save_trailing_requirements (reqs);
+          finish_scope();
+          --cp_unevaluated_operand;
+        }
+    }
   return current_template_reqs;
 }
 
-
 /* Declarators [gram.dcl.decl] */
 
 /* Parse an init-declarator.
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	(revision 212456)
+++ gcc/cp/decl.c	(working copy)
@@ -13864,6 +13864,30 @@  store_parm_decls (tree current_function_
     current_eh_spec_block = begin_eh_spec_block ();
 }
 
+// Bring the parameters of a function declaration back into 
+// scope without entering the function body. The declarator 
+// must be a function declarator. The caller is responsible 
+// for calling finish_scope.
+void
+push_function_parms (cp_declarator *declarator)
+{
+  // Find the actual function declarator.
+  while (declarator)
+    {
+      if (declarator->kind == cdk_function)
+        break;
+      declarator = declarator->declarator;
+    }
+
+  begin_scope (sk_function_parms, NULL_TREE);
+  tree p = declarator->u.function.parameters;
+  while (p != NULL_TREE && !VOID_TYPE_P (TREE_VALUE (p)))
+    {
+      pushdecl (TREE_VALUE (p));
+      p = TREE_CHAIN (p);
+    }
+}
+
 
 /* We have finished doing semantic analysis on DECL, but have not yet
    generated RTL for its body.  Save away our current state, so that
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 213130)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -5432,6 +5432,7 @@  extern bool defer_mark_used_calls;
 extern GTY(()) vec<tree, va_gc> *deferred_mark_used_calls;
 extern tree finish_case_label			(location_t, tree, tree);
 extern tree cxx_maybe_build_cleanup		(tree, tsubst_flags_t);
+extern void push_function_parms                (cp_declarator *);
 
 /* in decl2.c */
 extern bool check_java_method			(tree);