diff options
author | Jakub Jelinek <jakub@redhat.com> | 2017-05-26 11:17:54 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2017-05-26 11:17:54 +0200 |
commit | 6fc9f7aa731e895585c47d740509b5cd1591e797 (patch) | |
tree | d6a31e869ca764436905f87f10676d248ddddf01 /gcc/cp/cp-tree.h | |
parent | 28e0e05badfbdf7930bbd6f3051b07dd7ec37ae2 (diff) | |
download | gcc-6fc9f7aa731e895585c47d740509b5cd1591e797.zip gcc-6fc9f7aa731e895585c47d740509b5cd1591e797.tar.gz gcc-6fc9f7aa731e895585c47d740509b5cd1591e797.tar.bz2 |
cp-tree.h (struct lang_decl_decomp): New type.
* cp-tree.h (struct lang_decl_decomp): New type.
(struct lang_decl): Add u.decomp.
(LANG_DECL_DECOMP_CHECK): Define.
(DECL_DECOMPOSITION_P): Note it is set also on the vars
for user identifiers.
(DECL_DECOMP_BASE): Define.
(retrofit_lang_decl): Add extra int = 0 argument.
* lex.c (retrofit_lang_decl): Add SEL argument, if non-zero
use it to influence the selector choices and for selector
0 to non-zero transition copy old content.
(cxx_dup_lang_specific_decl): Handle DECL_DECOMPOSITION_P.
* decl.c (poplevel): For DECL_DECOMPOSITION_P, check
!DECL_DECOMP_BASE instead of !DECL_VALUE_EXPR. Adjust warning
wording if decl is a structured binding.
(cp_finish_decomp): Pass 4 as the new argument to retrofit_lang_decl.
Set DECL_DECOMP_BASE. Ignore DECL_READ_P sets from initialization
of individual variables for tuple structured bindings.
(grokdeclarator): Pass 4 as the new argument to retrofit_lang_decl.
Clear DECL_DECOMP_BASE.
* decl2.c (mark_used): Mark DECL_DECOMP_BASE TREE_USED as well.
* pt.c (tsubst_decomp_names): Assert DECL_DECOMP_BASE matches what
is expected.
* expr.c (mark_exp_read): Recurse on DECL_DECOMP_BASE instead of
DECL_VALUE_EXPR.
* g++.dg/cpp1z/decomp29.C (p): New variable.
(main): Add further tests.
From-SVN: r248483
Diffstat (limited to 'gcc/cp/cp-tree.h')
-rw-r--r-- | gcc/cp/cp-tree.h | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 514cb89..a471a63 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2516,6 +2516,15 @@ struct GTY(()) lang_decl_parm { int index; }; +/* Additional DECL_LANG_SPECIFIC information for structured bindings. */ + +struct GTY(()) lang_decl_decomp { + struct lang_decl_min min; + /* The artificial underlying "e" variable of the structured binding + variable. */ + tree base; +}; + /* DECL_LANG_SPECIFIC for all types. It would be nice to just make this a union rather than a struct containing a union as its only field, but tree.h declares it as a struct. */ @@ -2527,6 +2536,7 @@ struct GTY(()) lang_decl { struct lang_decl_fn GTY ((tag ("1"))) fn; struct lang_decl_ns GTY((tag ("2"))) ns; struct lang_decl_parm GTY((tag ("3"))) parm; + struct lang_decl_decomp GTY((tag ("4"))) decomp; } u; }; @@ -2563,6 +2573,13 @@ struct GTY(()) lang_decl { lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \ <->u.parm; }) +#define LANG_DECL_DECOMP_CHECK(NODE) __extension__ \ +({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \ + if (!VAR_P (NODE) \ + || lt->u.base.selector != 4) \ + lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \ + <->u.decomp; }) + #define LANG_DECL_U2_CHECK(NODE, TF) __extension__ \ ({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \ if (!LANG_DECL_HAS_MIN (NODE) || lt->u.base.u2sel != TF) \ @@ -2583,6 +2600,9 @@ struct GTY(()) lang_decl { #define LANG_DECL_PARM_CHECK(NODE) \ (&DECL_LANG_SPECIFIC (NODE)->u.parm) +#define LANG_DECL_DECOMP_CHECK(NODE) \ + (&DECL_LANG_SPECIFIC (NODE)->u.decomp) + #define LANG_DECL_U2_CHECK(NODE, TF) \ (&DECL_LANG_SPECIFIC (NODE)->u.min.u2) @@ -3816,8 +3836,8 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE))->u.base.var_declared_inline_p \ = true) -/* Nonzero if NODE is an artificial VAR_DECL for a C++17 decomposition - declaration. */ +/* Nonzero if NODE is an artificial VAR_DECL for a C++17 structured binding + declaration or one of VAR_DECLs for the user identifiers in it. */ #define DECL_DECOMPOSITION_P(NODE) \ (VAR_P (NODE) && DECL_LANG_SPECIFIC (NODE) \ ? DECL_LANG_SPECIFIC (NODE)->u.base.decomposition_p \ @@ -3826,6 +3846,10 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE))->u.base.decomposition_p \ = true) +/* The underlying artificial VAR_DECL for structured binding. */ +#define DECL_DECOMP_BASE(NODE) \ + (LANG_DECL_DECOMP_CHECK (NODE)->base) + /* Nonzero if NODE is an inline VAR_DECL. In C++17, static data members declared with constexpr specifier are implicitly inline variables. */ #define DECL_INLINE_VAR_P(NODE) \ @@ -6261,7 +6285,7 @@ extern tree unqualified_name_lookup_error (tree, extern tree unqualified_fn_lookup_error (cp_expr); extern tree build_lang_decl (enum tree_code, tree, tree); extern tree build_lang_decl_loc (location_t, enum tree_code, tree, tree); -extern void retrofit_lang_decl (tree); +extern void retrofit_lang_decl (tree, int = 0); extern tree copy_decl (tree CXX_MEM_STAT_INFO); extern tree copy_type (tree CXX_MEM_STAT_INFO); extern tree cxx_make_type (enum tree_code); |