From f3a880f8ce05db480187117358a742b6c27389e6 Mon Sep 17 00:00:00 2001 From: Adam Butcher Date: Fri, 13 Sep 2013 17:14:15 +0100 Subject: [PATCH] Revert r202554, r202540 and r202539. - 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 | 54 ---------- gcc/cp/Make-lang.in | 5 +- gcc/cp/cp-tree.h | 2 - gcc/cp/decl.c | 19 +--- gcc/cp/decl2.c | 5 +- gcc/cp/lambda.c | 189 ++++++----------------------------- gcc/cp/parser.c | 235 ++------------------------------------------ gcc/cp/parser.h | 6 -- gcc/cp/pt.c | 39 +++----- gcc/cp/type-utils.h | 55 ----------- 10 files changed, 64 insertions(+), 545 deletions(-) delete mode 100644 gcc/cp/type-utils.h diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 80e0d9623dc..ad47fef0314 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,62 +1,8 @@ -2013-09-13 Adam Butcher - - * lambda.c (maybe_add_lambda_conv_op): Initialize direct_argvec and call - to nullptr to avoid breakage with -Werror. - 2013-09-12 Brooks Moses PR driver/42955 * Make-lang.in: Do not install driver binaries in $(target)/bin. -2013-09-12 Adam Butcher - - * 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 - - * 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 * pt.c (instantiate_decl): Save/restore cp_unevaluated_operand and diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index 985f22b72d9..9a804346e4d 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -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 \ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 19e62727990..0d8bd9544ca 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 6e026b2e016..b4223aa5706 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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 % 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 % 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 % in parameter " - "declaration"); + error ("parameter declared %"); + type = error_mark_node; } /* A parameter declared as an array of T is really a pointer to T. diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index ac9dbd76b3f..d5d29127cfd 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -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))); diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index 0da22fdec6d..a53e692d48b 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -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 *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 *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 (); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 5dbae7536fb..e00e56c6e01 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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" /* The lexer. */ @@ -2064,11 +2063,6 @@ static vec *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 = ¶meters; 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, - ¶meter->decl_specifiers, - PARM, - parameter->default_argument != NULL_TREE, - ¶meter->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, + ¶meter->decl_specifiers, + PARM, + parameter->default_argument != NULL_TREE, + ¶meter->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" diff --git a/gcc/cp/parser.h b/gcc/cp/parser.h index ffdddaf4a08..3d8bb742d22 100644 --- a/gcc/cp/parser.h +++ b/gcc/cp/parser.h @@ -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 */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index de1022efec2..3ae679a055b 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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 index 3e82ca4f957..00000000000 --- a/gcc/cp/type-utils.h +++ /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 -. */ - -#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 -- 2.30.2