public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* [lambda] Latest experimental polymorphic lambda patches
@ 2009-08-11 12:11 Adam Butcher
  2009-08-11 16:21 ` Jason Merrill
  2013-04-22 16:42 ` Jason Merrill
  0 siblings, 2 replies; 10+ messages in thread
From: Adam Butcher @ 2009-08-11 12:11 UTC (permalink / raw)
  To: gcc; +Cc: jason, jfreeman08, adam.butcher, kde

[-- Attachment #1: Type: text/plain, Size: 2868 bytes --]

Attached are my latest experimental polymorphic lambda patches against the latest lambda branch.  Template parameters
implied by auto in the lambda's call parameter list no longer lose qualifiers.  The following examples produce
equivalent functions:

   1.   [] (auto x, auto& y, auto const& z) { return x + y + z; }
   2.   [] <typename X, typename Y, typename Z> (X x, Y& y, Z const& z) { return x + y + z; }
   3.   [] <typename Y> (auto x, Y& y, auto const& z) { return x + y + z; }

Note that using an explicit template parameter is only really useful if you wish to either a) ensure consistency among
a number of call parameters, b) use a non-type template parameter or c) specify a call parameter type constraint (or
other complex parameter type).

I have flattened the latest auto-template-inference changes with the previous one to remove complexity due to
re-arrangement.  In particular it no longer abuses decl.c -- those changes have currently moved into parser.c but it
is pretty clear that they have more in common with pt.c owing to a need to pull in some local static functions from
that file.  I intend to split or move parts (or most) into pt.c on my next attempt (if I get time to make one!)

There are currently many issues:
  - efficiency of template parameter list growing.
  - implicit return type deduction doesn't work from
    inside a template context if the lambda's return
    expression involves a dependent type.  Specifying
    decltype explicitly in these contexts is a
    workaround.
  - dependent inferred return type needs to be
    deferred and decayed.  This may go some way (all
    the way?) to solving the previous point.
  - location of implementation.
  - only a few use-cases have been considered.


Adam


Summary:

Subject: [PATCH] First pass polymorphic lambda support.

This commit adds experimental support for an optional template-parameter-list in angle-brackets at the start of a
lambda-parameter-declaration.
---
Subject: [PATCH] Restored decltype in lambda return type deduction for when expr is dependent.
---
Subject: [PATCH] Second version of typename inference from auto parameters in lambda call operator.

Still quite hacky -- though better than previous.  No longer loses
qualifiers on replaced auto parameters so is functionally closer to
what's really needed.

 - This is just a behavioural proof to find out how things work.
 - Need to shuffle some stuff into pt.c and do away with code dup.
 - Not sure how to free tree_vec's and tidy up the counts and sizes
   (looks like they're only intended to grow.)
 - Added `type_decays_to (non_reference (finish_decltype_type' as
   suggested by Jason.  Currently doesn't remove cv-quals from
   non-class types though.  Need to treat implicit return type
   differently for dependent types -- should defer and mark that it
   needs to be computed later.
---

[-- Attachment #2: 0001-First-pass-polymorphic-lambda-support.patch --]
[-- Type: application/octet-stream, Size: 3943 bytes --]

From f5c7881b713058d8dfdbf36081e5fb976c67d372 Mon Sep 17 00:00:00 2001
From: Adam Butcher <ajb@ccrvm001a.(none)>
Date: Tue, 4 Aug 2009 13:42:25 +0100
Subject: [PATCH] First pass polymorphic lambda support.

This commit adds experimental support for an optional template-parameter-list in angle-brackets at the start of a lambda-parameter-declaration.
---
 gcc/cp/parser.c    |   48 +++++++++++++++++++++++++++++++++++++++++++++++-
 gcc/cp/semantics.c |    3 +++
 2 files changed, 50 insertions(+), 1 deletions(-)

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index ec1dfec..36762ef 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -7160,9 +7160,13 @@ cp_parser_lambda_introducer (cp_parser* parser,
 /* Parse the (optional) middle of a lambda expression.
 
    lambda-parameter-declaration:
+       lambda-template-param-decl [opt]
      ( lambda-parameter-declaration-list [opt] ) exception-specification [opt]
        lambda-return-type-clause [opt]
 
+   lambda-template-param-decl:
+     < template-parameter-list >
+
    LAMBDA_EXPR is the current representation of the lambda expression.  */
 
 static void
@@ -7171,8 +7175,30 @@ cp_parser_lambda_parameter_declaration_opt (cp_parser* parser,
 {
   tree param_list = NULL_TREE;
   tree exception_spec = NULL_TREE;
+  tree template_param_list = NULL_TREE;
 
-  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+  if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
+    {
+      VEC (deferred_access_check,gc) *checks;
+    
+      cp_parser_require (parser, CPP_LESS, "%<<%>");
+
+      push_deferring_access_checks (dk_deferred);
+
+      template_param_list = cp_parser_template_parameter_list (parser);
+      
+      /* TODO: Actually use this at the pop site.  */
+      checks = get_deferred_access_checks ();
+
+      cp_parser_skip_to_end_of_template_parameter_list (parser);
+
+      /* We just processed one more parameter list.  */
+      ++parser->num_template_parameter_lists;
+
+      push_deferring_access_checks (dk_no_check);
+    }
+
+  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN) || template_param_list != NULL_TREE)
     {
       cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
 
@@ -7277,6 +7303,23 @@ cp_parser_lambda_parameter_declaration_opt (cp_parser* parser,
     DECL_INITIALIZED_IN_CLASS_P (fco) = 1;
     finish_method (fco);
 
+    if (template_param_list != NULL_TREE)
+      {
+        tree saved_current_function_decl = current_function_decl;
+        pop_deferring_access_checks ();
+
+        /* Clear current function decl to allow check_member_template
+           to pass.  Currently it rejects templates inside functions.
+           Couldn't figure out a clean way to test for lambda inside
+           check_member_template.  */
+        current_function_decl = NULL_TREE;
+        fco = finish_member_template_decl (fco);
+        current_function_decl = saved_current_function_decl;
+
+        --parser->num_template_parameter_lists;
+        pop_deferring_access_checks ();
+        finish_template_decl (template_param_list);
+      }
     finish_member_declaration (fco);
 
     LAMBDA_EXPR_FUNCTION (lambda_expr) = fco;
@@ -7315,6 +7358,9 @@ cp_parser_lambda_body (cp_parser* parser,
     tree fco = LAMBDA_EXPR_FUNCTION (lambda_expr);
     tree body;
 
+    if (DECL_FUNCTION_TEMPLATE_P (fco))
+      fco = DECL_TEMPLATE_RESULT (fco);
+
     /* Let the front end know that we are going to be defining this
        function.  */
     start_preparsed_function (fco,
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index e6f79c1..8318c46 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -5272,6 +5272,9 @@ deduce_lambda_return_type (tree lambda, tree expr)
   tree return_type;
   tree result;
 
+  if( TREE_CODE (fco) == TEMPLATE_DECL )
+    fco = DECL_TEMPLATE_RESULT (fco);
+
   return_type = type_decays_to (unlowered_expr_type (expr));
 
   /* Set the DECL_RESULT.
-- 
1.5.6.GIT


[-- Attachment #3: 0002-Restored-decltype-in-lambda-return-type-deduction-fo.patch --]
[-- Type: application/octet-stream, Size: 1060 bytes --]

From d6e34759c83abb6165c6ea4bfda902e39a825983 Mon Sep 17 00:00:00 2001
From: Adam Butcher <ajb@ccrvm001a.(none)>
Date: Fri, 7 Aug 2009 14:52:16 +0100
Subject: [PATCH] Restored decltype in lambda return type deduction for when expr is dependent.

---
 gcc/cp/semantics.c |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 8318c46..5f1aab0 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -5272,10 +5272,14 @@ deduce_lambda_return_type (tree lambda, tree expr)
   tree return_type;
   tree result;
 
-  if( TREE_CODE (fco) == TEMPLATE_DECL )
+  if (TREE_CODE (fco) == TEMPLATE_DECL)
     fco = DECL_TEMPLATE_RESULT (fco);
 
-  return_type = type_decays_to (unlowered_expr_type (expr));
+  if (type_dependent_expression_p (expr))
+    return_type = finish_decltype_type
+		   (expr, /*id_expression_or_member_access_p=*/false);
+  else
+    return_type = type_decays_to (unlowered_expr_type (expr));
 
   /* Set the DECL_RESULT.
      - start_preparsed_function
-- 
1.5.6.GIT


[-- Attachment #4: 0003-Second-version-of-typename-inference-from-auto-param.patch --]
[-- Type: application/octet-stream, Size: 12950 bytes --]

From 8d8f7c4b504df982a81d4ed95961a256d22f8367 Mon Sep 17 00:00:00 2001
From: Adam Butcher <ajb@localhost.(none)>
Date: Mon, 10 Aug 2009 23:45:06 +0100
Subject: [PATCH] Second version of typename inference from auto parameters in lambda call operator.

Still quite hacky -- though better than previous.  No longer loses
qualifiers on replaced auto parameters so is functionally closer to
what's really needed.

 - This is just a behavioural proof to find out how things work.
 - Need to shuffle some stuff into pt.c and do away with code dup.
 - Not sure how to free tree_vec's and tidy up the counts and sizes
   (looks like they're only intended to grow.)
 - Added `type_decays_to (non_reference (finish_decltype_type' as
   suggested by Jason.  Currently doesn't remove cv-quals from
   non-class types though.  Need to treat implicit return type
   differently for dependent types -- should defer and mark that it
   needs to be computed later.
---
 gcc/cp/parser.c    |  225 +++++++++++++++++++++++++++++++++++++++++++++++++---
 gcc/cp/pt.c        |    8 ++
 gcc/cp/semantics.c |    6 +-
 3 files changed, 226 insertions(+), 13 deletions(-)

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 36762ef..1461309 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -7032,7 +7032,7 @@ cp_parser_lambda_introducer (cp_parser* parser,
   /* Eat the leading `['.  */
   cp_parser_require (parser, CPP_OPEN_SQUARE, "%<[%>");
 
-  /* Record default capture mode.  "[&" "[=" "[&," "[=,"  */
+  /* Record default capture mode.  `[&' `[=' `[&,' `[=,'  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_AND)
       && cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_NAME)
     LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) = CPLD_REFERENCE;
@@ -7157,6 +7157,189 @@ cp_parser_lambda_introducer (cp_parser* parser,
 
 }
 
+
+/* The struct auto_parm_handler_t defines an interface for customizing
+   the behaviour when a C++0x `auto' type is found as the primary type
+   specifier of a function parameter declaration.
+   If auto_parm_handler is set whilst parsing a function parameter
+   list, the function auto_parm_handler->hook will be called for each
+   parameter having `auto' as its primary type; in each case the
+   result of the hook will be used to replace `auto' as the primary
+   type.  */
+typedef struct auto_parm_handler_t auto_parm_handler_t;
+typedef tree (*auto_parm_hook_t) (auto_parm_handler_t*);
+struct auto_parm_handler_t
+{
+   auto_parm_hook_t hook;
+};
+/* Set to a structure that provides the above interface to be called
+   if a type containing `auto' is found during
+   cp_parser_parameter_declaration_list.  */
+auto_parm_handler_t* auto_parm_handler = 0;
+
+/* Handler state for processing `auto' found in lambda function call
+   parameter list.  Supports implicit polymorphic lambdas.  */
+typedef struct lambda_auto_handler_t
+{
+   auto_parm_hook_t hook;
+   tree* template_param_list;
+   VEC (deferred_access_check,gc)* checks;
+   cp_parser* parser;
+   int i;
+}
+lambda_auto_handler_t;
+
+/* FIXME: Much of this would appear to fit better in pt.c.  */
+
+/* FIXME: It would also mean the copied function
+          build_template_parm_index and rudely extern'd
+          x_canonical_type_parameter would be unnecessary.  */
+
+tree lambda_parameter_make_auto_type_name
+  (lambda_auto_handler_t*);
+tree lambda_auto_handler
+  (lambda_auto_handler_t*);
+
+tree
+lambda_parameter_make_auto_type_name (lambda_auto_handler_t* handler)
+{
+  char buf[32];
+  sprintf (buf, "__AutoT%d", ++handler->i);
+  return get_identifier (buf);
+}
+
+/* Return a new TEMPLATE_PARM_INDEX with the indicated INDEX, LEVEL,
+   ORIG_LEVEL, DECL, and TYPE.  
+   FIXME: Remove this copy from here; i.e. probably move rest into
+          pt.c.  */
+
+static tree
+build_template_parm_index (int index,
+			   int level,
+			   int orig_level,
+			   tree decl,
+			   tree type)
+{
+  tree t = make_node (TEMPLATE_PARM_INDEX);
+  TEMPLATE_PARM_IDX (t) = index;
+  TEMPLATE_PARM_LEVEL (t) = level;
+  TEMPLATE_PARM_ORIG_LEVEL (t) = orig_level;
+  TEMPLATE_PARM_DECL (t) = decl;
+  TREE_TYPE (t) = type;
+  TREE_CONSTANT (t) = TREE_CONSTANT (decl);
+  TREE_READONLY (t) = TREE_READONLY (decl);
+
+  return t;
+}
+
+tree
+lambda_auto_handler (lambda_auto_handler_t* handler)
+{
+  struct cp_binding_level* scope = current_binding_level;
+  location_t param_loc = cp_lexer_peek_token (handler->parser->lexer)->location; /* XXX: Any way to get current location? */
+
+  /* First auto parameter may need to start a template parameter list.  */
+  bool become_template = *handler->template_param_list == NULL_TREE;
+
+  tree synth_id = lambda_parameter_make_auto_type_name (handler);
+  tree synth_tmpl_parm = finish_template_type_parm (class_type_node, synth_id);
+  synth_tmpl_parm = build_tree_list (NULL_TREE, synth_tmpl_parm);
+
+  if (become_template)
+    {
+      /* do something rude and pretend that the template parameter
+	 scope surrounds the function definition.  XXX: can we
+	 guarantee that the immediate-outer scope /is/ the fco? */
+      current_binding_level = current_binding_level->level_chain;
+
+      /*if (ENABLE_SCOPE_CHECKING)
+	--binding_depth;*/
+
+      push_deferring_access_checks (dk_deferred);
+      begin_template_parm_list ();
+    }
+
+  synth_tmpl_parm = process_template_parm (0,
+				       param_loc,
+				       synth_tmpl_parm,
+				       /*non_type=*/false,
+				       /*param_pack=*/false);
+
+  /* Re-index based on last existing parameter.  */
+  if (!become_template)
+    {
+      tree old = *handler->template_param_list;
+      size_t len = TREE_VEC_LENGTH (old);
+      size_t idx;
+      extern tree x_canonical_type_parameter (tree);
+
+      tree p = TREE_VALUE (TREE_VEC_ELT (old, --len));
+      if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL)
+	idx = TEMPLATE_TYPE_IDX (TREE_TYPE (p));
+      else
+	idx = TEMPLATE_PARM_IDX (DECL_INITIAL (p));
+
+      ++idx;
+
+      TEMPLATE_TYPE_PARM_INDEX (TREE_TYPE (synth_id))
+	= build_template_parm_index (idx, processing_template_decl,
+				     processing_template_decl,
+				     TYPE_NAME (TREE_TYPE (synth_id)),
+				     TREE_TYPE (synth_id));
+      TYPE_CANONICAL (TREE_TYPE (synth_id)) = x_canonical_type_parameter (TREE_TYPE (synth_id));
+    }
+
+  if (become_template)
+    {
+      /* Initial template parameter, create new list.  */
+      *handler->template_param_list = end_template_parm_list (synth_tmpl_parm);
+      ++handler->parser->num_template_parameter_lists;
+      push_deferring_access_checks (dk_no_check);
+      push_binding_level (scope);
+    }
+  else /* Add to existing template parameter list.  */
+    {
+      tree old = *handler->template_param_list;
+      tree new_vec;
+      size_t len;
+
+      gcc_assert (TREE_CODE (old) == TREE_VEC);
+
+      len = TREE_VEC_LENGTH (old);
+
+      /* XXX: Maybe do doubling and store real length in handler
+	 state, there doesn't seem to be any way to free these; or
+	 rather no way to free them that tidies up the
+	 tree_node_counts and sizes.  Ideally just want a
+	 realloc_tree_vec or some such thing that would do realloc and
+	 housekeeping.  Maybe there's some reason why this
+         would be a bad thing. (?)  In fact it would be better
+         to keep building a tree list and only flatten into
+         a vector after parsing the parameter list. */
+      new_vec = make_tree_vec (len+1);
+      {
+	size_t n;
+	for (n = 0; n != len; ++n)
+	  TREE_VEC_ELT (new_vec, n) = TREE_VEC_ELT (old, n);
+      }
+      TREE_VEC_ELT (new_vec, len) = synth_tmpl_parm;
+     /* memcpy (new_vec, old, sizeof (struct tree_vec) + sizeof (tree) * (len-1));
+      TREE_VEC_LENGTH (new_vec) = ++len;
+      */
+
+      /* XXX: free old one - how?  maybe ggc_free? but how to tidy up
+       * the node counts and sizes? */
+      ggc_free (old);
+
+      *handler->template_param_list = new_vec;
+
+      TREE_VALUE (current_template_parms) = new_vec;
+    }
+
+  /* Return synthesized type as a substitute for `auto'. */
+  return TREE_TYPE (synth_id);
+}
+
 /* Parse the (optional) middle of a lambda expression.
 
    lambda-parameter-declaration:
@@ -7176,11 +7359,10 @@ cp_parser_lambda_parameter_declaration_opt (cp_parser* parser,
   tree param_list = NULL_TREE;
   tree exception_spec = NULL_TREE;
   tree template_param_list = NULL_TREE;
+  VEC (deferred_access_check,gc) *checks = 0;
 
   if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
     {
-      VEC (deferred_access_check,gc) *checks;
-    
       cp_parser_require (parser, CPP_LESS, "%<<%>");
 
       push_deferring_access_checks (dk_deferred);
@@ -7208,10 +7390,23 @@ cp_parser_lambda_parameter_declaration_opt (cp_parser* parser,
       if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
         {
           bool is_error = false;
+
+	  /* Set up handler for auto being used in function parameter list.  */
+	  lambda_auto_handler_t auto_handler;
+	  auto_handler.hook = (auto_parm_hook_t) lambda_auto_handler;
+	  auto_handler.template_param_list = &template_param_list;
+	  auto_handler.checks = 0;
+	  auto_handler.parser = parser;
+	  auto_handler.i = 0;
+	  auto_parm_handler = (auto_parm_handler_t*) &auto_handler;
+
           param_list = cp_parser_parameter_declaration_list (parser, &is_error);
           /* TODO: better way to handle this error?  */
           if (is_error)
             param_list = NULL_TREE;
+
+	  /* TODO: copy auto_handler.checks out */
+	  auto_parm_handler = 0;
         }
 
       cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
@@ -7307,6 +7502,7 @@ cp_parser_lambda_parameter_declaration_opt (cp_parser* parser,
       {
         tree saved_current_function_decl = current_function_decl;
         pop_deferring_access_checks ();
+	/* TODO: do checks */
 
         /* Clear current function decl to allow check_member_template
            to pass.  Currently it rejects templates inside functions.
@@ -7316,16 +7512,14 @@ cp_parser_lambda_parameter_declaration_opt (cp_parser* parser,
         fco = finish_member_template_decl (fco);
         current_function_decl = saved_current_function_decl;
 
-        --parser->num_template_parameter_lists;
+	--parser->num_template_parameter_lists;
         pop_deferring_access_checks ();
         finish_template_decl (template_param_list);
       }
     finish_member_declaration (fco);
 
     LAMBDA_EXPR_FUNCTION (lambda_expr) = fco;
-
   }
-
 }
 
 /* Parse the body of a lambda expression, which is simply
@@ -14656,11 +14850,20 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error)
       deprecated_state = DEPRECATED_SUPPRESS;
 
       if (parameter)
-	decl = grokdeclarator (parameter->declarator,
-			       &parameter->decl_specifiers,
-			       PARM,
-			       parameter->default_argument != NULL_TREE,
-			       &parameter->decl_specifiers.attributes);
+	{
+	  /* If there is a custom `auto' handler and the primary type
+	     of this parameter is `auto', then invoke the hook and
+	     replace `auto' with the result. */
+	  if (auto_parm_handler && is_auto (parameter->decl_specifiers.type))
+	    {
+	      parameter->decl_specifiers.type = auto_parm_handler->hook (auto_parm_handler);
+	    }
+	  decl = grokdeclarator (parameter->declarator,
+				 &parameter->decl_specifiers,
+				 PARM,
+				 parameter->default_argument != NULL_TREE,
+				 &parameter->decl_specifiers.attributes);
+	}
 
       deprecated_state = DEPRECATED_NORMAL;
 
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index ed45324..2d8380c 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -3150,6 +3150,13 @@ canonical_type_parameter (tree type)
     }
 }
 
+/* FIXME: Cleanup this mess */
+tree x_canonical_type_parameter (tree type);
+tree x_canonical_type_parameter (tree type)
+{
+  return canonical_type_parameter (type);
+}
+
 /* Return a TEMPLATE_PARM_INDEX, similar to INDEX, but whose
    TEMPLATE_PARM_LEVEL has been decreased by LEVELS.  If such a
    TEMPLATE_PARM_INDEX already exists, it is returned; otherwise, a
@@ -17480,6 +17487,7 @@ is_auto (const_tree type)
 tree
 type_uses_auto (tree type)
 {
+  /* XXX: Maybe to loop rather than recurse here? */
   enum tree_code code;
   if (is_auto (type))
     return type;
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 5f1aab0..482887c 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -5276,8 +5276,10 @@ deduce_lambda_return_type (tree lambda, tree expr)
     fco = DECL_TEMPLATE_RESULT (fco);
 
   if (type_dependent_expression_p (expr))
-    return_type = finish_decltype_type
-		   (expr, /*id_expression_or_member_access_p=*/false);
+    /* TODO: Should defer this until instantiation rather than using
+             decltype.  */
+    return_type = type_decays_to (non_reference (finish_decltype_type
+		   (expr, /*id_expression_or_member_access_p=*/false)));
   else
     return_type = type_decays_to (unlowered_expr_type (expr));
 
-- 
1.5.6.GIT


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2013-06-12 20:27 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-08-11 12:11 [lambda] Latest experimental polymorphic lambda patches Adam Butcher
2009-08-11 16:21 ` Jason Merrill
2009-08-12  0:03   ` Adam Butcher
2009-08-12  1:00     ` Jason Merrill
2009-09-11 18:57   ` Ian Lance Taylor
2013-04-22 16:42 ` Jason Merrill
2013-04-23 13:42   ` Jason Merrill
2013-04-27 14:40     ` Adam Butcher
2013-06-12 20:27       ` [lambda] First stage remake of old " Adam Butcher
2013-06-12 20:27         ` [PATCH] Remake initial changes from old lambda branch to support explicit lambda template support and fixup against mainline gcc/cp changes Adam Butcher

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).