]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Revert r202554, r202540 and r202539.
authorAdam Butcher <abutcher@gcc.gnu.org>
Fri, 13 Sep 2013 16:14:15 +0000 (17:14 +0100)
committerAdam Butcher <abutcher@gcc.gnu.org>
Fri, 13 Sep 2013 16:14:15 +0000 (17:14 +0100)
 - r202554: Fix uninitialized variables causing breakage with -Werror.
 - r202540: Support using 'auto' in a function parameter list to introduce an implicit template parameter.
 - r202539: Support lambda templates.

From-SVN: r202570

gcc/cp/ChangeLog
gcc/cp/Make-lang.in
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/lambda.c
gcc/cp/parser.c
gcc/cp/parser.h
gcc/cp/pt.c
gcc/cp/type-utils.h [deleted file]

index 80e0d9623dc4b8d1e919b28b35d8ee972c259a65..ad47fef03140ae13721b4d32f33e13a9568fc3f2 100644 (file)
@@ -1,62 +1,8 @@
-2013-09-13  Adam Butcher  <adam@jessamine.co.uk>
-
-       * lambda.c (maybe_add_lambda_conv_op): Initialize direct_argvec and call
-       to nullptr to avoid breakage with -Werror.
-
 2013-09-12  Brooks Moses  <bmoses@google.com>
 
        PR driver/42955
        * Make-lang.in: Do not install driver binaries in $(target)/bin.
 
-2013-09-12  Adam Butcher  <adam@jessamine.co.uk>
-
-       * cp-tree.h (type_uses_auto_or_concept): Declare.
-       (is_auto_or_concept): Declare.
-       * decl.c (grokdeclarator): Allow 'auto' parameters in lambdas with
-       -std=gnu++1y or -std=c++1y or, as a GNU extension, in plain functions.
-       * type-utils.h: New header defining ...
-       (find_type_usage): ... this new function based on pt.c (type_uses_auto)
-       for searching a type tree given a predicate.
-       * pt.c (type_uses_auto): Reimplement via type-utils.h (find_type_usage).
-       (is_auto_or_concept): New function.
-       (type_uses_auto_or_concept): New function.
-       * parser.h (struct cp_parser): Add fully_implicit_function_template_p.
-       * parser.c (cp_parser_new): Initialize fully_implicit_function_template_p.
-       (cp_parser_new): Initialize fully_implicit_function_template_p.
-       (cp_parser_lambda_expression): Copy and restore value of
-       fully_implicit_function_template_p as per other parser fields.
-       (cp_parser_parameter_declaration_list): Count generic
-       parameters and call ...
-       (add_implicit_template_parms): ... this new function to synthesize them
-       with help from type-utils.h (find_type_usage), ...
-       (tree_type_is_auto_or_concept): ... this new static function and ...
-       (make_generic_type_name): ... this new static function.
-       (cp_parser_direct_declarator): Account for implicit template parameters.
-       (cp_parser_lambda_declarator_opt): Finish fully implicit template if
-       necessary by calling ...
-       (finish_fully_implicit_template): ... this new function.
-       (cp_parser_member_declaration): Likewise.
-       (cp_parser_function_definition_after_declarator): Likewise.
-       * Make-lang.in (cp/pt.o): Add dependency on type-utils.h.
-       (cp/parser.o): Likewise.
-
-2013-09-12  Adam Butcher  <adam@jessamine.co.uk>
-
-       * parser.c (cp_parser_lambda_declarator_opt): Accept template parameter
-       list with std=c++1y or std=gnu++1y.
-       (cp_parser_lambda_body): Don't call 'expand_or_defer_fn' for lambda call
-       operator template to avoid adding template result to symbol table.
-       * lambda.c (lambda_function): Return template result if call operator is
-       a template.
-       (maybe_add_lambda_conv_op): Move declarations to point of use.  Refactor
-       operator call building in order to support conversion of a non-capturing
-       lambda template to a function pointer with help from ...
-       (prepare_op_call): ... this new function.
-       * decl2.c (check_member_template): Don't reject lambda call operator
-       template in local [lambda] class.
-       * pt.c (instantiate_class_template_1): Don't instantiate lambda call
-       operator template when instantiating lambda class.
-
 2013-09-12  Adam Butcher  <adam@jessamine.co.uk>
 
        * pt.c (instantiate_decl): Save/restore cp_unevaluated_operand and
index 985f22b72d9d646a24f93cd6503c39fc3aa94c16..9a804346e4d840c9e416d96d18c8e7d1d468396e 100644 (file)
@@ -312,7 +312,7 @@ cp/except.o: cp/except.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) \
 cp/expr.o: cp/expr.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) $(TM_P_H)
 cp/pt.o: cp/pt.c $(CXX_TREE_H) $(TM_H) cp/decl.h cp/cp-objcp-common.h \
   toplev.h $(TREE_INLINE_H) pointer-set.h gt-cp-pt.h intl.h \
-  c-family/c-objc.h cp/type-utils.h
+  c-family/c-objc.h
 cp/error.o: cp/error.c $(CXX_TREE_H) $(TM_H) $(DIAGNOSTIC_H) \
   $(FLAGS_H) $(REAL_H) $(LANGHOOKS_DEF_H) $(CXX_PRETTY_PRINT_H) \
   tree-diagnostic.h tree-pretty-print.h pointer-set.h c-family/c-objc.h
@@ -331,8 +331,7 @@ cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) $(REAL_H) \
   gt-cp-mangle.h $(TARGET_H) $(TM_P_H) $(CGRAPH_H)
 cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) $(DIAGNOSTIC_CORE_H) \
   gt-cp-parser.h $(TARGET_H) $(PLUGIN_H) intl.h cp/decl.h \
-  c-family/c-objc.h tree-pretty-print.h $(CXX_PARSER_H) $(TIMEVAR_H) \
-  cp/type-utils.h
+  c-family/c-objc.h tree-pretty-print.h $(CXX_PARSER_H) $(TIMEVAR_H)
 cp/cp-gimplify.o: cp/cp-gimplify.c $(CXX_TREE_H) $(C_COMMON_H) \
        $(TM_H) coretypes.h pointer-set.h tree-iterator.h $(SPLAY_TREE_H)
 cp/vtable-class-hierarchy.o: cp/vtable-class-hierarchy.c \
index 19e62727990bb7139ccc379c71b50e31c53c5857..0d8bd9544ca1bd4cd0cf734b2117f7827c7fd588 100644 (file)
@@ -5455,12 +5455,10 @@ extern tree make_auto                           (void);
 extern tree make_decltype_auto                 (void);
 extern tree do_auto_deduction                  (tree, tree, tree);
 extern tree type_uses_auto                     (tree);
-extern tree type_uses_auto_or_concept          (tree);
 extern void append_type_to_template_for_access_check (tree, tree, tree,
                                                      location_t);
 extern tree splice_late_return_type            (tree, tree);
 extern bool is_auto                            (const_tree);
-extern bool is_auto_or_concept                 (const_tree);
 extern tree process_template_parm              (tree, location_t, tree, 
                                                 bool, bool);
 extern tree end_template_parm_list             (tree);
index 6e026b2e01670e281b2da97f6dbd42e607927a08..b4223aa5706358db5f57f8403e6d0dd1fa40fe92 100644 (file)
@@ -10320,23 +10320,8 @@ grokdeclarator (const cp_declarator *declarator,
 
       if (type_uses_auto (type))
        {
-         if (current_class_type && LAMBDA_TYPE_P (current_class_type))
-           {
-             if (cxx_dialect < cxx1y)
-               pedwarn (location_of (type), 0,
-                        "use of %<auto%> in lambda parameter declaration "
-                        "only available with "
-                        "-std=c++1y or -std=gnu++1y");
-           }
-         else if (cxx_dialect < cxx1y)
-           pedwarn (location_of (type), 0,
-                    "use of %<auto%> in parameter declaration "
-                    "only available with "
-                    "-std=c++1y or -std=gnu++1y");
-         else
-           pedwarn (location_of (type), OPT_Wpedantic,
-                    "ISO C++ forbids use of %<auto%> in parameter "
-                    "declaration");
+         error ("parameter declared %<auto%>");
+         type = error_mark_node;
        }
 
       /* A parameter declared as an array of T is really a pointer to T.
index ac9dbd76b3f370040044328f38477672e11698ed..d5d29127cfd269ddd349db113834c9a408141516 100644 (file)
@@ -507,9 +507,8 @@ check_member_template (tree tmpl)
       || (TREE_CODE (decl) == TYPE_DECL
          && MAYBE_CLASS_TYPE_P (TREE_TYPE (decl))))
     {
-      /* The parser rejects template declarations in local classes
-        (with the exception of generic lambdas).  */
-      gcc_assert (!current_function_decl || LAMBDA_FUNCTION_P (decl));
+      /* The parser rejects template declarations in local classes.  */
+      gcc_assert (!current_function_decl);
       /* The parser rejects any use of virtual in a function template.  */
       gcc_assert (!(TREE_CODE (decl) == FUNCTION_DECL
                    && DECL_VIRTUAL_P (decl)));
index 0da22fdec6d9b88ea3e234634667becaa2af706a..a53e692d48b462ca94db0bb456681cf45d833c29 100644 (file)
@@ -196,7 +196,7 @@ lambda_function (tree lambda)
                          /*protect=*/0, /*want_type=*/false,
                          tf_warning_or_error);
   if (lambda)
-    lambda = STRIP_TEMPLATE (get_first_fn (lambda));
+    lambda = BASELINK_FUNCTIONS (lambda);
   return lambda;
 }
 
@@ -741,22 +741,6 @@ nonlambda_method_basetype (void)
   return TYPE_METHOD_BASETYPE (TREE_TYPE (fn));
 }
 
-/* Helper function for maybe_add_lambda_conv_op; build a CALL_EXPR with
-   indicated FN and NARGS, but do not initialize the return type or any of the
-   argument slots.  */
-
-static tree
-prepare_op_call (tree fn, int nargs)
-{
-  tree t;
-
-  t = build_vl_exp (CALL_EXPR, nargs + 3);
-  CALL_EXPR_FN (t) = fn;
-  CALL_EXPR_STATIC_CHAIN (t) = NULL;
-
-  return t;
-}
-
 /* If the closure TYPE has a static op(), also add a conversion to function
    pointer.  */
 
@@ -765,6 +749,9 @@ maybe_add_lambda_conv_op (tree type)
 {
   bool nested = (current_function_decl != NULL_TREE);
   tree callop = lambda_function (type);
+  tree rettype, name, fntype, fn, body, compound_stmt;
+  tree thistype, stattype, statfn, convfn, call, arg;
+  vec<tree, va_gc> *argvec;
 
   if (LAMBDA_EXPR_CAPTURE_LIST (CLASSTYPE_LAMBDA_EXPR (type)) != NULL_TREE)
     return;
@@ -772,10 +759,6 @@ maybe_add_lambda_conv_op (tree type)
   if (processing_template_decl)
     return;
 
-  bool const generic_lambda_p
-    = (DECL_TEMPLATE_INFO (callop)
-    && DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (callop)) == callop);
-
   if (DECL_INITIAL (callop) == NULL_TREE)
     {
       /* If the op() wasn't instantiated due to errors, give up.  */
@@ -783,127 +766,16 @@ maybe_add_lambda_conv_op (tree type)
       return;
     }
 
-  /* Non-template conversion operators are defined directly with build_call_a
-     and using DIRECT_ARGVEC for arguments (including 'this').  Templates are
-     deferred and the CALL is built in-place.  In the case of a deduced return
-     call op, the decltype expression, DECLTYPE_CALL, used as a substitute for
-     the return type is also built in-place.  The arguments of DECLTYPE_CALL in
-     the return expression may differ in flags from those in the body CALL.  In
-     particular, parameter pack expansions are marked PACK_EXPANSION_LOCAL_P in
-     the body CALL, but not in DECLTYPE_CALL.  */
-
-  vec<tree, va_gc> *direct_argvec = 0;
-  tree decltype_call = 0, call = 0;
-  tree fn_result = TREE_TYPE (TREE_TYPE (callop));
-
-  if (generic_lambda_p)
-    {
-      /* Prepare the dependent member call for the static member function
-        '_FUN' and, potentially, prepare another call to be used in a decltype
-        return expression for a deduced return call op to allow for simple
-        implementation of the conversion operator.  */
-
-      tree instance = build_nop (type, null_pointer_node);
-      tree objfn = build_min (COMPONENT_REF, NULL_TREE,
-                             instance, DECL_NAME (callop), NULL_TREE);
-      int nargs = list_length (DECL_ARGUMENTS (callop)) - 1;
-
-      call = prepare_op_call (objfn, nargs);
-      if (type_uses_auto (fn_result))
-       decltype_call = prepare_op_call (objfn, nargs);
-    }
-  else
-    {
-      direct_argvec = make_tree_vector ();
-      direct_argvec->quick_push (build1 (NOP_EXPR,
-                                        TREE_TYPE (DECL_ARGUMENTS (callop)),
-                                        null_pointer_node));
-    }
-
-  /* Copy CALLOP's argument list (as per 'copy_list') as FN_ARGS in order to
-     declare the static member function "_FUN" below.  For each arg append to
-     DIRECT_ARGVEC (for the non-template case) or populate the pre-allocated
-     call args (for the template case).  If a parameter pack is found, expand
-     it, flagging it as PACK_EXPANSION_LOCAL_P for the body call.  */
-
-  tree fn_args = NULL_TREE;
-  {
-    int ix = 0;
-    tree src = DECL_CHAIN (DECL_ARGUMENTS (callop));
-    tree tgt;
-
-    while (src)
-      {
-       tree new_node = copy_node (src);
-
-       if (!fn_args)
-         fn_args = tgt = new_node;
-       else
-         {
-           TREE_CHAIN (tgt) = new_node;
-           tgt = new_node;
-         }
-
-       mark_exp_read (tgt);
-
-       if (generic_lambda_p)
-         {
-           if (FUNCTION_PARAMETER_PACK_P (tgt))
-             {
-               tree a = make_pack_expansion (tgt);
-               if (decltype_call)
-                 CALL_EXPR_ARG (decltype_call, ix) = copy_node (a);
-               PACK_EXPANSION_LOCAL_P (a) = true;
-               CALL_EXPR_ARG (call, ix) = a;
-             }
-           else
-             {
-               tree a = convert_from_reference (tgt);
-               CALL_EXPR_ARG (call, ix) = a;
-               if (decltype_call)
-                 CALL_EXPR_ARG (decltype_call, ix) = copy_node (a);
-             }
-           ++ix;
-         }
-       else
-         vec_safe_push (direct_argvec, tgt);
-
-       src = TREE_CHAIN (src);
-      }
-  }
-
-
-  if (generic_lambda_p)
-    {
-      if (decltype_call)
-       {
-         ++processing_template_decl;
-         fn_result = finish_decltype_type
-           (decltype_call, /*id_expression_or_member_access_p=*/false,
-            tf_warning_or_error);
-         --processing_template_decl;
-       }
-    }
-  else
-    {
-      call = build_call_a (callop,
-                          direct_argvec->length (),
-                          direct_argvec->address ());
-      if (MAYBE_CLASS_TYPE_P (TREE_TYPE (call)))
-       call = build_cplus_new (TREE_TYPE (call), call, tf_warning_or_error);
-    }
-  CALL_FROM_THUNK_P (call) = 1;
-
-  tree stattype = build_function_type (fn_result, FUNCTION_ARG_CHAIN (callop));
+  stattype = build_function_type (TREE_TYPE (TREE_TYPE (callop)),
+                                 FUNCTION_ARG_CHAIN (callop));
 
   /* First build up the conversion op.  */
 
-  tree rettype = build_pointer_type (stattype);
-  tree name = mangle_conv_op_name_for_type (rettype);
-  tree thistype = cp_build_qualified_type (type, TYPE_QUAL_CONST);
-  tree fntype = build_method_type_directly (thistype, rettype, void_list_node);
-  tree convfn = build_lang_decl (FUNCTION_DECL, name, fntype);
-  tree fn = convfn;
+  rettype = build_pointer_type (stattype);
+  name = mangle_conv_op_name_for_type (rettype);
+  thistype = cp_build_qualified_type (type, TYPE_QUAL_CONST);
+  fntype = build_method_type_directly (thistype, rettype, void_list_node);
+  fn = convfn = build_lang_decl (FUNCTION_DECL, name, fntype);
   DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (callop);
 
   if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
@@ -922,9 +794,6 @@ maybe_add_lambda_conv_op (tree type)
   if (nested)
     DECL_INTERFACE_KNOWN (fn) = 1;
 
-  if (generic_lambda_p)
-    fn = add_inherited_template_parms (fn, DECL_TI_TEMPLATE (callop));
-
   add_method (type, fn, NULL_TREE);
 
   /* Generic thunk code fails for varargs; we'll complain in mark_used if
@@ -938,8 +807,7 @@ maybe_add_lambda_conv_op (tree type)
   /* Now build up the thunk to be returned.  */
 
   name = get_identifier ("_FUN");
-  tree statfn = build_lang_decl (FUNCTION_DECL, name, stattype);
-  fn = statfn;
+  fn = statfn = build_lang_decl (FUNCTION_DECL, name, stattype);
   DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (callop);
   if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
       && DECL_ALIGN (fn) < 2 * BITS_PER_UNIT)
@@ -952,8 +820,8 @@ maybe_add_lambda_conv_op (tree type)
   DECL_NOT_REALLY_EXTERN (fn) = 1;
   DECL_DECLARED_INLINE_P (fn) = 1;
   DECL_STATIC_FUNCTION_P (fn) = 1;
-  DECL_ARGUMENTS (fn) = fn_args;
-  for (tree arg = fn_args; arg; arg = DECL_CHAIN (arg))
+  DECL_ARGUMENTS (fn) = copy_list (DECL_CHAIN (DECL_ARGUMENTS (callop)));
+  for (arg = DECL_ARGUMENTS (fn); arg; arg = DECL_CHAIN (arg))
     {
       /* Avoid duplicate -Wshadow warnings.  */
       DECL_NAME (arg) = NULL_TREE;
@@ -962,9 +830,6 @@ maybe_add_lambda_conv_op (tree type)
   if (nested)
     DECL_INTERFACE_KNOWN (fn) = 1;
 
-  if (generic_lambda_p)
-    fn = add_inherited_template_parms (fn, DECL_TI_TEMPLATE (callop));
-
   add_method (type, fn, NULL_TREE);
 
   if (nested)
@@ -985,17 +850,29 @@ maybe_add_lambda_conv_op (tree type)
         ((symtab_node) cgraph_get_create_node (statfn),
           (symtab_node) cgraph_get_create_node (callop));
     }
-  tree body = begin_function_body ();
-  tree compound_stmt = begin_compound_stmt (0);
+  body = begin_function_body ();
+  compound_stmt = begin_compound_stmt (0);
+
+  arg = build1 (NOP_EXPR, TREE_TYPE (DECL_ARGUMENTS (callop)),
+               null_pointer_node);
+  argvec = make_tree_vector ();
+  argvec->quick_push (arg);
+  for (arg = DECL_ARGUMENTS (statfn); arg; arg = DECL_CHAIN (arg))
+    {
+      mark_exp_read (arg);
+      vec_safe_push (argvec, arg);
+    }
+  call = build_call_a (callop, argvec->length (), argvec->address ());
+  CALL_FROM_THUNK_P (call) = 1;
+  if (MAYBE_CLASS_TYPE_P (TREE_TYPE (call)))
+    call = build_cplus_new (TREE_TYPE (call), call, tf_warning_or_error);
   call = convert_from_reference (call);
   finish_return_stmt (call);
 
   finish_compound_stmt (compound_stmt);
   finish_function_body (body);
 
-  fn = finish_function (/*inline*/2);
-  if (!generic_lambda_p)
-    expand_or_defer_fn (fn);
+  expand_or_defer_fn (finish_function (2));
 
   /* Generate the body of the conversion op.  */
 
@@ -1011,9 +888,7 @@ maybe_add_lambda_conv_op (tree type)
   finish_compound_stmt (compound_stmt);
   finish_function_body (body);
 
-  fn = finish_function (/*inline*/2);
-  if (!generic_lambda_p)
-    expand_or_defer_fn (fn);
+  expand_or_defer_fn (finish_function (2));
 
   if (nested)
     pop_function_context ();
index 5dbae7536fbc34f24d59edea4aebbc63ae7862ae..e00e56c6e012a7cf0f9f8e6206f65ab47e56d0ad 100644 (file)
@@ -38,7 +38,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "plugin.h"
 #include "tree-pretty-print.h"
 #include "parser.h"
-#include "type-utils.h"
 
 \f
 /* The lexer.  */
@@ -2064,11 +2063,6 @@ static vec<constructor_elt, va_gc> *cp_parser_initializer_list
 static bool cp_parser_ctor_initializer_opt_and_function_body
   (cp_parser *, bool);
 
-static tree add_implicit_template_parms
-  (cp_parser *, size_t, tree);
-static tree finish_fully_implicit_template
-  (cp_parser *, tree);
-
 /* Classes [gram.class] */
 
 static tree cp_parser_class_name
@@ -3391,9 +3385,6 @@ cp_parser_new (void)
   /* No template parameters apply.  */
   parser->num_template_parameter_lists = 0;
 
-  /* Not declaring an implicit function template.  */
-  parser->fully_implicit_function_template_p = false;
-
   return parser;
 }
 
@@ -8558,12 +8549,10 @@ cp_parser_lambda_expression (cp_parser* parser)
         = parser->num_template_parameter_lists;
     unsigned char in_statement = parser->in_statement;
     bool in_switch_statement_p = parser->in_switch_statement_p;
-    bool fully_implicit_function_template_p = parser->fully_implicit_function_template_p;
 
     parser->num_template_parameter_lists = 0;
     parser->in_statement = 0;
     parser->in_switch_statement_p = false;
-    parser->fully_implicit_function_template_p = false;
 
     /* By virtue of defining a local class, a lambda expression has access to
        the private variables of enclosing classes.  */
@@ -8587,7 +8576,6 @@ cp_parser_lambda_expression (cp_parser* parser)
     parser->num_template_parameter_lists = saved_num_template_parameter_lists;
     parser->in_statement = in_statement;
     parser->in_switch_statement_p = in_switch_statement_p;
-    parser->fully_implicit_function_template_p = fully_implicit_function_template_p;
   }
 
   pop_deferring_access_checks ();
@@ -8795,7 +8783,6 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
 /* Parse the (optional) middle of a lambda expression.
 
    lambda-declarator:
-     < template-parameter-list [opt] >
      ( parameter-declaration-clause [opt] )
        attribute-specifier [opt]
        mutable [opt]
@@ -8815,30 +8802,9 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
   tree param_list = void_list_node;
   tree attributes = NULL_TREE;
   tree exception_spec = NULL_TREE;
-  tree template_param_list = NULL_TREE;
-
-  /* The template-parameter-list is optional, but must begin with
-     an opening angle if present.  */
-  if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
-    {
-      if (cxx_dialect < cxx1y)
-       pedwarn (parser->lexer->next_token->location, 0,
-                "lambda templates are only available with "
-                "-std=c++1y or -std=gnu++1y");
-
-      cp_lexer_consume_token (parser->lexer);
-
-      template_param_list = cp_parser_template_parameter_list (parser);
 
-      cp_parser_skip_to_end_of_template_parameter_list (parser);
-
-      /* We just processed one more parameter list.  */
-      ++parser->num_template_parameter_lists;
-    }
-
-  /* The parameter-declaration-clause is optional (unless
-     template-parameter-list was given), but must begin with an
-     opening parenthesis if present.  */
+  /* The lambda-declarator is optional, but must begin with an opening
+     parenthesis if present.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
     {
       cp_lexer_consume_token (parser->lexer);
@@ -8881,8 +8847,6 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
          trailing-return-type in case of decltype.  */
       pop_bindings_and_leave_scope ();
     }
-  else if (template_param_list != NULL_TREE) // generate diagnostic
-    cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
 
   /* Create the function call operator.
 
@@ -8926,14 +8890,6 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
        DECL_ARTIFICIAL (fco) = 1;
        /* Give the object parameter a different name.  */
        DECL_NAME (DECL_ARGUMENTS (fco)) = get_identifier ("__closure");
-       if (template_param_list)
-         {
-           fco = finish_member_template_decl (fco);
-           finish_template_decl (template_param_list);
-           --parser->num_template_parameter_lists;
-         }
-       else if (parser->fully_implicit_function_template_p)
-         fco = finish_fully_implicit_template (parser, fco);
       }
 
     finish_member_declaration (fco);
@@ -9056,11 +9012,7 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
     finish_lambda_scope ();
 
     /* Finish the function and generate code for it if necessary.  */
-    tree fn = finish_function (/*inline*/2);
-
-    /* Only expand if the call op is not a template.  */
-    if (!DECL_TEMPLATE_INFO (fco))
-      expand_or_defer_fn (fn);
+    expand_or_defer_fn (finish_function (/*inline*/2));
   }
 
   parser->local_variables_forbidden_p = local_variables_forbidden_p;
@@ -16804,10 +16756,8 @@ cp_parser_direct_declarator (cp_parser* parser,
              /* Parse the parameter-declaration-clause.  */
              params = cp_parser_parameter_declaration_clause (parser);
 
-             /* Restore saved template parameter lists accounting for implicit
-                template parameters.  */
              parser->num_template_parameter_lists
-               += saved_num_template_parameter_lists;
+               = saved_num_template_parameter_lists;
 
              /* Consume the `)'.  */
              cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
@@ -17905,7 +17855,6 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error)
   tree *tail = &parameters; 
   bool saved_in_unbraced_linkage_specification_p;
   int index = 0;
-  int implicit_template_parms = 0;
 
   /* Assume all will go well.  */
   *is_error = false;
@@ -17933,18 +17882,11 @@ 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 (TREE_TYPE (decl) != error_mark_node
-             && parameter->decl_specifiers.type
-             && is_auto_or_concept (parameter->decl_specifiers.type))
-             ++implicit_template_parms;
-       }
+       decl = grokdeclarator (parameter->declarator,
+                              &parameter->decl_specifiers,
+                              PARM,
+                              parameter->default_argument != NULL_TREE,
+                              &parameter->decl_specifiers.attributes);
 
       deprecated_state = DEPRECATED_NORMAL;
 
@@ -18032,11 +17974,6 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error)
   parser->in_unbraced_linkage_specification_p
     = saved_in_unbraced_linkage_specification_p;
 
-  if (parameters != error_mark_node && implicit_template_parms)
-    parameters = add_implicit_template_parms (parser,
-                                             implicit_template_parms,
-                                             parameters);
-
   return parameters;
 }
 
@@ -20043,11 +19980,7 @@ cp_parser_member_declaration (cp_parser* parser)
                                                              attributes);
                  /* If the member was not a friend, declare it here.  */
                  if (!friend_p)
-                   {
-                     if (parser->fully_implicit_function_template_p)
-                       decl = finish_fully_implicit_template (parser, decl);
-                     finish_member_declaration (decl);
-                   }
+                   finish_member_declaration (decl);
                  /* Peek at the next token.  */
                  token = cp_lexer_peek_token (parser->lexer);
                  /* If the next token is a semicolon, consume it.  */
@@ -20063,8 +19996,6 @@ cp_parser_member_declaration (cp_parser* parser)
                                  initializer, /*init_const_expr_p=*/true,
                                  asm_specification,
                                  attributes);
-               if (parser->fully_implicit_function_template_p)
-                 decl = finish_fully_implicit_template (parser, decl);
            }
 
          /* Reset PREFIX_ATTRIBUTES.  */
@@ -22332,9 +22263,6 @@ cp_parser_function_definition_after_declarator (cp_parser* parser,
     = saved_num_template_parameter_lists;
   parser->in_function_body = saved_in_function_body;
 
-  if (parser->fully_implicit_function_template_p)
-    finish_fully_implicit_template (parser, /*member_decl_opt=*/0);
-
   return fn;
 }
 
@@ -28880,147 +28808,4 @@ c_parse_file (void)
   the_parser = NULL;
 }
 
-/* Create an identifier for a generic parameter type (a synthesized
-   template parameter implied by `auto' or a concept identifier). */
-
-static tree
-make_generic_type_name (int i)
-{
-  char buf[32];
-  sprintf (buf, "__GenT%d", i);
-  return get_identifier (buf);
-}
-
-/* Predicate that behaves as is_auto_or_concept but matches the parent
-   node of the generic type rather than the generic type itself.  This
-   allows for type transformation in add_implicit_template_parms.  */
-
-static inline bool
-tree_type_is_auto_or_concept (const_tree t)
-{
-  return TREE_TYPE (t) && is_auto_or_concept (TREE_TYPE (t));
-}
-
-/* Add COUNT implicit template parameters gleaned from the generic
-   type parameters in PARAMETERS to the CURRENT_TEMPLATE_PARMS
-   (creating a new template parameter list if necessary).  Returns
-   PARAMETERS suitably rewritten to reference the newly created types
-   or ERROR_MARK_NODE on failure.  */
-
-tree
-add_implicit_template_parms (cp_parser *parser, size_t count, tree parameters)
-{
-  gcc_assert (current_binding_level->kind == sk_function_parms);
-
-  cp_binding_level *fn_parms_scope = current_binding_level;
-
-  bool become_template =
-    fn_parms_scope->level_chain->kind != sk_template_parms;
-
-  size_t synth_idx = 0;
-
-  /* Roll back a scope level and either introduce a new template parameter list
-     or update an existing one.  The function scope is added back after template
-     parameter synthesis below.  */
-  current_binding_level = fn_parms_scope->level_chain;
-
-  /* TPARMS tracks the function's template parameter list.  This is either a new
-     chain in the case of a fully implicit function template or an extension of
-     the function's explicitly specified template parameter list.  */
-  tree tparms = NULL_TREE;
-
-  if (become_template)
-    {
-      push_deferring_access_checks (dk_deferred);
-      begin_template_parm_list ();
-
-      parser->fully_implicit_function_template_p = true;
-      ++parser->num_template_parameter_lists;
-    }
-  else
-    {
-      /* Roll back the innermost template parameter list such that it may be
-        extended in the loop below as if it were being explicitly declared.  */
-
-      gcc_assert (current_template_parms);
-
-      /* Pop the innermost template parms into TPARMS.  */
-      tree inner_vec = INNERMOST_TEMPLATE_PARMS (current_template_parms);
-      current_template_parms = TREE_CHAIN (current_template_parms);
-
-      size_t inner_vec_len = TREE_VEC_LENGTH (inner_vec);
-      if (inner_vec_len != 0)
-       {
-         tree t = tparms = TREE_VEC_ELT (inner_vec, 0);
-         for (size_t n = 1; n < inner_vec_len; ++n)
-           t = TREE_CHAIN (t) = TREE_VEC_ELT (inner_vec, n);
-       }
-
-      ++processing_template_parmlist;
-    }
-
-  for (tree p = parameters; p && synth_idx < count; p = TREE_CHAIN (p))
-    {
-      tree generic_type_ptr
-       = find_type_usage (TREE_VALUE (p), tree_type_is_auto_or_concept);
-
-      if (!generic_type_ptr)
-       continue;
-
-      tree synth_id = make_generic_type_name (synth_idx++);
-      tree synth_tmpl_parm = finish_template_type_parm (class_type_node,
-                                                       synth_id);
-      tparms = process_template_parm (tparms, DECL_SOURCE_LOCATION (TREE_VALUE
-                                                                   (p)),
-                                     build_tree_list (NULL_TREE,
-                                                      synth_tmpl_parm),
-                                     /*non_type=*/false,
-                                     /*param_pack=*/false);
-
-      /* Rewrite the type of P to be the template_parm added above (getdecls is
-         used to retrieve it since it is the most recent declaration in this
-         scope).  Qualifiers need to be preserved also.  */
-
-      tree& cur_type = TREE_TYPE (generic_type_ptr);
-      tree new_type = TREE_TYPE (getdecls ());
-
-      if (TYPE_QUALS (cur_type))
-       cur_type = cp_build_qualified_type (new_type, TYPE_QUALS (cur_type));
-      else
-       cur_type = new_type;
-    }
-
-  gcc_assert (synth_idx == count);
-
-  push_binding_level (fn_parms_scope);
-
-  end_template_parm_list (tparms);
-
-  return parameters;
-}
-
-/* Finish the declaration of a fully implicit function template.  Such a
-   template has no explicit template parameter list so has not been through the
-   normal template head and tail processing.  add_implicit_template_parms tries
-   to do the head; this tries to do the tail.  MEMBER_DECL_OPT should be
-   provided if the declaration is a class member such that its template
-   declaration can be completed.  If MEMBER_DECL_OPT is provided the finished
-   form is returned.  Otherwise NULL_TREE is returned. */
-
-tree
-finish_fully_implicit_template (cp_parser *parser, tree member_decl_opt)
-{
-  gcc_assert (parser->fully_implicit_function_template_p);
-
-  pop_deferring_access_checks ();
-  if (member_decl_opt)
-    member_decl_opt = finish_member_template_decl (member_decl_opt);
-  end_template_decl ();
-
-  parser->fully_implicit_function_template_p = false;
-  --parser->num_template_parameter_lists;
-
-  return member_decl_opt;
-}
-
 #include "gt-cp-parser.h"
index ffdddaf4a08f25d8b55a1b64b1f8d1f5b1907111..3d8bb742d221c4bf3814257ac9adb9f81ba8eedd 100644 (file)
@@ -341,12 +341,6 @@ typedef struct GTY(()) cp_parser {
   /* The number of template parameter lists that apply directly to the
      current declaration.  */
   unsigned num_template_parameter_lists;
-
-  /* TRUE if the function being declared was made a template due to its
-     parameter list containing generic type specifiers (`auto' or concept
-     identifiers) rather than an explicit template parameter list.  */
-  bool fully_implicit_function_template_p;
-
 } cp_parser;
 
 /* In parser.c  */
index de1022efec27dfc1a4b74ec7f872527b35e4946a..3ae679a055b1d8a6357661a44391c879849b383f 100644 (file)
@@ -41,7 +41,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "toplev.h"
 #include "timevar.h"
 #include "tree-iterator.h"
-#include "type-utils.h"
 
 /* The type of functions taking a tree, and some additional data, and
    returning an int.  */
@@ -9104,9 +9103,7 @@ instantiate_class_template_1 (tree type)
       tree decl = lambda_function (type);
       if (decl)
        {
-         if (!DECL_TEMPLATE_INFO (decl)
-             || DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl)) != decl)
-           instantiate_decl (decl, false, false);
+         instantiate_decl (decl, false, false);
 
          /* We need to instantiate the capture list from the template
             after we've instantiated the closure members, but before we
@@ -21111,35 +21108,31 @@ is_auto (const_tree type)
     return false;
 }
 
-/* Returns the TEMPLATE_TYPE_PARM in TYPE representing `auto' iff TYPE contains
-   a use of `auto'.  Returns NULL_TREE otherwise.  */
+/* Returns true iff TYPE contains a use of 'auto'.  Since auto can only
+   appear as a type-specifier for the declaration in question, we don't
+   have to look through the whole type.  */
 
 tree
 type_uses_auto (tree type)
 {
-  return find_type_usage (type, is_auto);
-}
+  enum tree_code code;
+  if (is_auto (type))
+    return type;
 
-/* Returns true iff TYPE is a TEMPLATE_TYPE_PARM representing 'auto',
-   'decltype(auto)' or a concept.  */
+  code = TREE_CODE (type);
 
-bool
-is_auto_or_concept (const_tree type)
-{
-  return is_auto (type); // or concept
-}
+  if (code == POINTER_TYPE || code == REFERENCE_TYPE
+      || code == OFFSET_TYPE || code == FUNCTION_TYPE
+      || code == METHOD_TYPE || code == ARRAY_TYPE)
+    return type_uses_auto (TREE_TYPE (type));
 
-/* Returns the TEMPLATE_TYPE_PARM in TYPE representing a generic type (`auto' or
-   a concept identifier) iff TYPE contains a use of a generic type.  Returns
-   NULL_TREE otherwise.  */
+  if (TYPE_PTRMEMFUNC_P (type))
+    return type_uses_auto (TREE_TYPE (TREE_TYPE
+                                  (TYPE_PTRMEMFUNC_FN_TYPE (type))));
 
-tree
-type_uses_auto_or_concept (tree type)
-{
-  return find_type_usage (type, is_auto_or_concept);
+  return NULL_TREE;
 }
 
-
 /* For a given template T, return the vector of typedefs referenced
    in T for which access check is needed at T instantiation time.
    T is either  a FUNCTION_DECL or a RECORD_TYPE.
diff --git a/gcc/cp/type-utils.h b/gcc/cp/type-utils.h
deleted file mode 100644 (file)
index 3e82ca4..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Utilities for querying and manipulating type trees.
-   Copyright (C) 2013 Free Software Foundation, Inc.
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
-
-GCC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3.  If not see
-<http://www.gnu.org/licenses/>.  */
-
-#ifndef GCC_CP_TYPE_UTILS_H
-#define GCC_CP_TYPE_UTILS_H
-
-/* Returns the first tree within T that is directly matched by PRED.  T may be a
-   type or PARM_DECL and is incrementally decomposed toward its type-specifier
-   until a match is found.  NULL_TREE is returned if PRED does not match any
-   part of T.
-
-   This is primarily intended for detecting whether T uses `auto' or a concept
-   identifier.  Since either of these can only appear as a type-specifier for
-   the declaration in question, only top-level qualifications are traversed;
-   find_type_usage does not look through the whole type.  */
-
-inline tree
-find_type_usage (tree t, bool (*pred) (const_tree))
-{
-  enum tree_code code;
-  if (pred (t))
-    return t;
-
-  code = TREE_CODE (t);
-
-  if (code == POINTER_TYPE || code == REFERENCE_TYPE
-      || code == PARM_DECL || code == OFFSET_TYPE
-      || code == FUNCTION_TYPE || code == METHOD_TYPE
-      || code == ARRAY_TYPE)
-    return find_type_usage (TREE_TYPE (t), pred);
-
-  if (TYPE_PTRMEMFUNC_P (t))
-    return find_type_usage
-      (TREE_TYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (t))), pred);
-
-  return NULL_TREE;
-}
-
-#endif // GCC_CP_TYPE_UTILS_H