aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/lambda.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2016-08-09 00:33:58 -0400
committerJason Merrill <jason@gcc.gnu.org>2016-08-09 00:33:58 -0400
commit98e5a19af592e5329ae7d991ad8d9e9b7b81be37 (patch)
treec6df51387a49c0bebc8f02921379e3e80cdba861 /gcc/cp/lambda.c
parent7dc2b4a235481acda5ae9e51f4cc0401b1fb192f (diff)
downloadgcc-98e5a19af592e5329ae7d991ad8d9e9b7b81be37.zip
gcc-98e5a19af592e5329ae7d991ad8d9e9b7b81be37.tar.gz
gcc-98e5a19af592e5329ae7d991ad8d9e9b7b81be37.tar.bz2
Implement C++17 constexpr lambda.
gcc/c-family/ * c-cppbuiltin.c (c_cpp_builtins): Update __cpp_constexpr for C++17 constexpr lambdas. gcc/cp/ * class.c (finalize_literal_type_property): Handle lambdas. * constexpr.c (is_valid_constexpr_fn): Likewise. No longer static. (explain_invalid_constexpr_fn, cxx_eval_call_expression): Handle lambdas. (cxx_eval_constant_expression): Handle capture proxy. (var_in_constexpr_fn): Don't check for C++14. (var_in_maybe_constexpr_fn): New. (potential_constant_expression_1): Use it. Check DECL_EXPR for declarations not allowed in constexpr function. * decl.c (make_rtl_for_nonlocal_decl): Use var_in_maybe_constexpr_fn. (finish_function): Set DECL_DECLARED_CONSTEXPR_P on lambda members. * lambda.c (begin_lambda_type): Set CLASSTYPE_LITERAL_P. (maybe_add_lambda_conv_op): Clear thunk CALL_EXPR location. (lambda_static_thunk_p): New. * parser.c (cp_keyword_starts_decl_specifier_p): Add RID_CONSTEXPR. (CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR): New enumerator. (cp_parser_decl_specifier_seq): Handle it. (cp_parser_lambda_declarator_opt): Use cp_parser_decl_specifier_seq. * pt.c (instantiate_class_template_1): Set CLASSTYPE_LITERAL_P. (tsubst_copy_and_build) [CALL_EXPR]: Propagate CALL_FROM_THUNK_P. * error.c (dump_function_decl): Check TFF_NO_TEMPLATE_BINDINGS. (dump_expr) [FUNCTION_DECL]: Pass it. From-SVN: r239268
Diffstat (limited to 'gcc/cp/lambda.c')
-rw-r--r--gcc/cp/lambda.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index 978fa0d..d511185 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -154,6 +154,11 @@ begin_lambda_type (tree lambda)
LAMBDA_EXPR_CLOSURE (lambda) = type;
CLASSTYPE_LAMBDA_EXPR (type) = lambda;
+ /* In C++17, assume the closure is literal; we'll clear the flag later if
+ necessary. */
+ if (cxx_dialect >= cxx1z)
+ CLASSTYPE_LITERAL_P (type) = true;
+
/* Clear base types. */
xref_basetypes (type, /*bases=*/NULL_TREE);
@@ -1004,6 +1009,7 @@ maybe_add_lambda_conv_op (tree type)
direct_argvec->address ());
CALL_FROM_THUNK_P (call) = 1;
+ SET_EXPR_LOCATION (call, UNKNOWN_LOCATION);
tree stattype = build_function_type (fn_result, FUNCTION_ARG_CHAIN (callop));
stattype = (cp_build_type_attribute_variant
@@ -1141,6 +1147,18 @@ maybe_add_lambda_conv_op (tree type)
--function_depth;
}
+/* True if FN is the static function "_FUN" that gets returned from the lambda
+ conversion operator. */
+
+bool
+lambda_static_thunk_p (tree fn)
+{
+ return (fn && TREE_CODE (fn) == FUNCTION_DECL
+ && DECL_ARTIFICIAL (fn)
+ && DECL_STATIC_FUNCTION_P (fn)
+ && LAMBDA_TYPE_P (CP_DECL_CONTEXT (fn)));
+}
+
/* Returns true iff VAL is a lambda-related declaration which should
be ignored by unqualified lookup. */