implementation of the conversion operator. */
tree instance = cp_build_fold_indirect_ref (thisarg);
- tree objfn = build_min (COMPONENT_REF, NULL_TREE,
- instance, DECL_NAME (callop), NULL_TREE);
+ tree objfn = lookup_template_function (DECL_NAME (callop),
+ DECL_TI_ARGS (callop));
+ objfn = build_min (COMPONENT_REF, NULL_TREE,
+ instance, objfn, NULL_TREE);
int nargs = list_length (DECL_ARGUMENTS (callop)) - 1;
call = prepare_op_call (objfn, nargs);
if (generic_lambda_p)
{
- /* Avoid capturing variables in this context. */
- ++cp_unevaluated_operand;
- tree a = forward_parm (tgt);
- --cp_unevaluated_operand;
-
+ tree a = tgt;
+ if (DECL_PACK_P (tgt))
+ {
+ a = make_pack_expansion (a);
+ PACK_EXPANSION_LOCAL_P (a) = true;
+ }
CALL_EXPR_ARG (call, ix) = a;
- if (decltype_call)
- CALL_EXPR_ARG (decltype_call, ix) = unshare_expr (a);
- if (PACK_EXPANSION_P (a))
- /* Set this after unsharing so it's not in decltype_call. */
- PACK_EXPANSION_LOCAL_P (a) = true;
+ if (decltype_call)
+ {
+ /* Avoid capturing variables in this context. */
+ ++cp_unevaluated_operand;
+ CALL_EXPR_ARG (decltype_call, ix) = forward_parm (tgt);
+ --cp_unevaluated_operand;
+ }
++ix;
}
}
}
+ /* Stripped-down processing for a call in a thunk. Specifically, in
+ the thunk template for a generic lambda. */
+ if (CALL_FROM_THUNK_P (t))
+ {
+ tree thisarg = NULL_TREE;
+ if (TREE_CODE (function) == COMPONENT_REF)
+ {
+ thisarg = TREE_OPERAND (function, 0);
+ if (TREE_CODE (thisarg) == INDIRECT_REF)
+ thisarg = TREE_OPERAND (thisarg, 0);
+ function = TREE_OPERAND (function, 1);
+ if (TREE_CODE (function) == BASELINK)
+ function = BASELINK_FUNCTIONS (function);
+ }
+ /* We aren't going to do normal overload resolution, so force the
+ template-id to resolve. */
+ function = resolve_nondeduced_context (function, complain);
+ for (unsigned i = 0; i < nargs; ++i)
+ {
+ /* In a thunk, pass through args directly, without any
+ conversions. */
+ tree arg = (*call_args)[i];
+ while (TREE_CODE (arg) != PARM_DECL)
+ arg = TREE_OPERAND (arg, 0);
+ (*call_args)[i] = arg;
+ }
+ if (thisarg)
+ {
+ /* Shift the other args over to make room. */
+ vec_safe_push (call_args, (*call_args)[nargs-1]);
+ for (int i = nargs-1; i > 0; --i)
+ (*call_args)[i] = (*call_args)[i-1];
+ (*call_args)[0] = thisarg;
+ }
+ ret = build_call_a (function, call_args->length (),
+ call_args->address ());
+ /* The thunk location is not interesting. */
+ SET_EXPR_LOCATION (ret, UNKNOWN_LOCATION);
+ CALL_FROM_THUNK_P (ret) = true;
+ if (CLASS_TYPE_P (TREE_TYPE (ret)))
+ CALL_EXPR_RETURN_SLOT_OPT (ret) = true;
+
+ release_tree_vector (call_args);
+ RETURN (ret);
+ }
+
/* We do not perform argument-dependent lookup if normal
lookup finds a non-function, in accordance with the
expected resolution of DR 218. */
bool op = CALL_EXPR_OPERATOR_SYNTAX (t);
bool ord = CALL_EXPR_ORDERED_ARGS (t);
bool rev = CALL_EXPR_REVERSE_ARGS (t);
- bool thk = CALL_FROM_THUNK_P (t);
- if (op || ord || rev || thk)
+ if (op || ord || rev)
{
function = extract_call_expr (ret);
CALL_EXPR_OPERATOR_SYNTAX (function) = op;
CALL_EXPR_ORDERED_ARGS (function) = ord;
CALL_EXPR_REVERSE_ARGS (function) = rev;
- if (thk)
- {
- if (TREE_CODE (function) == CALL_EXPR)
- CALL_FROM_THUNK_P (function) = true;
- else
- AGGR_INIT_FROM_THUNK_P (function) = true;
- /* The thunk location is not interesting. */
- SET_EXPR_LOCATION (function, UNKNOWN_LOCATION);
- }
}
}