diff options
author | Adam Butcher <abutcher@gcc.gnu.org> | 2013-09-13 17:14:15 +0100 |
---|---|---|
committer | Adam Butcher <abutcher@gcc.gnu.org> | 2013-09-13 17:14:15 +0100 |
commit | f3a880f8ce05db480187117358a742b6c27389e6 (patch) | |
tree | b3a6ccfb5b51b1de42bc371b1ac6993f040d4704 /gcc/cp/lambda.c | |
parent | 19ba6aab7b0980c7c07ec76426541c7fea430c15 (diff) | |
download | gcc-f3a880f8ce05db480187117358a742b6c27389e6.zip gcc-f3a880f8ce05db480187117358a742b6c27389e6.tar.gz gcc-f3a880f8ce05db480187117358a742b6c27389e6.tar.bz2 |
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
Diffstat (limited to 'gcc/cp/lambda.c')
-rw-r--r-- | gcc/cp/lambda.c | 189 |
1 files changed, 32 insertions, 157 deletions
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index 0da22fd..a53e692 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<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 (); |