diff options
author | Nathan Sidwell <nathan@acm.org> | 2017-05-31 16:46:58 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2017-05-31 16:46:58 +0000 |
commit | 91e920c9390f5293fdc84fbf9859dab53d7454b0 (patch) | |
tree | 4c41fc434e3fb47d6867bccb8b227635de1ff46b /gcc/cp/lex.c | |
parent | 3909991c7b89c99e28d4b8ed2a2de740adb1d432 (diff) | |
download | gcc-91e920c9390f5293fdc84fbf9859dab53d7454b0.zip gcc-91e920c9390f5293fdc84fbf9859dab53d7454b0.tar.gz gcc-91e920c9390f5293fdc84fbf9859dab53d7454b0.tar.bz2 |
cp-tree.h (lang_decl_slector): New enum.
* cp-tree.h (lang_decl_slector): New enum.
(lang_decl_base): Make selector an enum. Drop decomposition_p
field.
(lang_decl): Use enum for discrimination.
(LANG_DECL_FN_CHECK, LANG_DECL_NS_CHECK, LANG_DECL_PARM_CHECK,
LANG_DECL_DEOMP_CHECK): Use enum.
(DECL_DECOMPOSITION_P): Use selector value.
(SET_DECL_DECOMPOSITION_P): Delete.
(retrofit_lang_decl): Lose SEL parm.
(fit_decomposition_lang_decl): Declare.
* decl.c (cp_finish_decomp, grokdeclarator): Use
fit_decomposition_lang_decl.
* lex.c (maybe_add_lang_decl_raw): New. Broken out of
retrofit_lang_decl.
(set_decl_linkage): New. Broken out of retrofit_lang_decl. Use
enum.
(fit_decomposition_lang_decl): Likewise.
(retrofit_lang_decl): Use worker functions.
(cxx_dup_lang_specific_decl): Use selector enum.
(maybe_add_lang_type_raw): New. Broken out of ...
(cxx_make_type_name): ... here. Call it.
From-SVN: r248748
Diffstat (limited to 'gcc/cp/lex.c')
-rw-r--r-- | gcc/cp/lex.c | 162 |
1 files changed, 106 insertions, 56 deletions
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 1b4eb35..5dc9eee 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -525,53 +525,52 @@ build_lang_decl_loc (location_t loc, enum tree_code code, tree name, tree type) return t; } -/* Add DECL_LANG_SPECIFIC info to T. Called from build_lang_decl - and pushdecl (for functions generated by the back end). */ +/* Maybe add a raw lang_decl to T, a decl. Return true if it needed + one. */ -void -retrofit_lang_decl (tree t, int sel) +static bool +maybe_add_lang_decl_raw (tree t, bool decomp_p) { - struct lang_decl *ld; size_t size; - size_t oldsize = 0; - - if (DECL_LANG_SPECIFIC (t)) - { - if (sel) - { - if (DECL_LANG_SPECIFIC (t)->u.base.selector == sel) - return; - gcc_assert (DECL_LANG_SPECIFIC (t)->u.base.selector == 0); - oldsize = sizeof (struct lang_decl_min); - } - else - return; - } + lang_decl_selector sel; - if (sel == 4) - size = sizeof (struct lang_decl_decomp); + if (decomp_p) + sel = lds_decomp, size = sizeof (struct lang_decl_decomp); else if (TREE_CODE (t) == FUNCTION_DECL) - sel = 1, size = sizeof (struct lang_decl_fn); + sel = lds_fn, size = sizeof (struct lang_decl_fn); else if (TREE_CODE (t) == NAMESPACE_DECL) - sel = 2, size = sizeof (struct lang_decl_ns); + sel = lds_ns, size = sizeof (struct lang_decl_ns); else if (TREE_CODE (t) == PARM_DECL) - sel = 3, size = sizeof (struct lang_decl_parm); + sel = lds_parm, size = sizeof (struct lang_decl_parm); else if (LANG_DECL_HAS_MIN (t)) - sel = 0, size = sizeof (struct lang_decl_min); + sel = lds_min, size = sizeof (struct lang_decl_min); else - gcc_unreachable (); + return false; - ld = (struct lang_decl *) ggc_internal_cleared_alloc (size); - if (oldsize) - memcpy (ld, DECL_LANG_SPECIFIC (t), oldsize); + struct lang_decl *ld + = (struct lang_decl *) ggc_internal_cleared_alloc (size); ld->u.base.selector = sel; DECL_LANG_SPECIFIC (t) = ld; - if (sel == 2) + if (sel == lds_ns) /* Who'd create a namespace, only to put nothing in it? */ ld->u.ns.bindings = hash_map<lang_identifier *, tree>::create_ggc (499); + if (GATHER_STATISTICS) + { + tree_node_counts[(int)lang_decl] += 1; + tree_node_sizes[(int)lang_decl] += size; + } + return true; +} + +/* T has just had a decl_lang_specific added. Initialize its + linkage. */ + +static void +set_decl_linkage (tree t) +{ if (current_lang_name == lang_name_cplusplus || decl_linkage (t) == lk_none) SET_DECL_LANGUAGE (t, lang_cplusplus); @@ -579,37 +578,79 @@ retrofit_lang_decl (tree t, int sel) SET_DECL_LANGUAGE (t, lang_c); else gcc_unreachable (); +} - if (GATHER_STATISTICS) +/* T is a VAR_DECL node that needs to be a decomposition of BASE. */ + +void +fit_decomposition_lang_decl (tree t, tree base) +{ + if (struct lang_decl *orig_ld = DECL_LANG_SPECIFIC (t)) { - tree_node_counts[(int)lang_decl] += 1; - tree_node_sizes[(int)lang_decl] += size; + if (orig_ld->u.base.selector == lds_min) + { + maybe_add_lang_decl_raw (t, true); + memcpy (DECL_LANG_SPECIFIC (t), orig_ld, + sizeof (struct lang_decl_min)); + /* Reset selector, which will have been bashed by the + memcpy. */ + DECL_LANG_SPECIFIC (t)->u.base.selector = lds_decomp; + } + else + gcc_checking_assert (orig_ld->u.base.selector == lds_decomp); + } + else + { + maybe_add_lang_decl_raw (t, true); + set_decl_linkage (t); } + + DECL_DECOMP_BASE (t) = base; +} + +/* Add DECL_LANG_SPECIFIC info to T, if it needs one. Generally + every C++ decl needs one, but C builtins etc do not. */ + +void +retrofit_lang_decl (tree t) +{ + if (DECL_LANG_SPECIFIC (t)) + return; + + if (maybe_add_lang_decl_raw (t, false)) + set_decl_linkage (t); } void cxx_dup_lang_specific_decl (tree node) { int size; - struct lang_decl *ld; if (! DECL_LANG_SPECIFIC (node)) return; - if (TREE_CODE (node) == FUNCTION_DECL) - size = sizeof (struct lang_decl_fn); - else if (TREE_CODE (node) == NAMESPACE_DECL) - size = sizeof (struct lang_decl_ns); - else if (TREE_CODE (node) == PARM_DECL) - size = sizeof (struct lang_decl_parm); - else if (DECL_DECOMPOSITION_P (node)) - size = sizeof (struct lang_decl_decomp); - else if (LANG_DECL_HAS_MIN (node)) - size = sizeof (struct lang_decl_min); - else - gcc_unreachable (); + switch (DECL_LANG_SPECIFIC (node)->u.base.selector) + { + case lds_min: + size = sizeof (struct lang_decl_min); + break; + case lds_fn: + size = sizeof (struct lang_decl_fn); + break; + case lds_ns: + size = sizeof (struct lang_decl_ns); + break; + case lds_parm: + size = sizeof (struct lang_decl_parm); + break; + case lds_decomp: + size = sizeof (struct lang_decl_decomp); + break; + default: + gcc_unreachable (); + } - ld = (struct lang_decl *) ggc_internal_alloc (size); + struct lang_decl *ld = (struct lang_decl *) ggc_internal_alloc (size); memcpy (ld, DECL_LANG_SPECIFIC (node), size); DECL_LANG_SPECIFIC (node) = ld; @@ -670,18 +711,18 @@ copy_type (tree type MEM_STAT_DECL) return copy; } -tree -cxx_make_type (enum tree_code code) -{ - tree t = make_node (code); +/* Add a raw lang_type to T, a type, should it need one. */ - /* Create lang_type structure. */ - if (RECORD_OR_UNION_CODE_P (code) - || code == BOUND_TEMPLATE_TEMPLATE_PARM) +static bool +maybe_add_lang_type_raw (tree t) +{ + bool add = (RECORD_OR_UNION_CODE_P (TREE_CODE (t)) + || TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM); + if (add) { struct lang_type *pi - = (struct lang_type *) ggc_internal_cleared_alloc - (sizeof (struct lang_type)); + = (struct lang_type *) ggc_internal_cleared_alloc + (sizeof (struct lang_type)); TYPE_LANG_SPECIFIC (t) = pi; pi->u.c.h.is_lang_type_class = 1; @@ -692,6 +733,15 @@ cxx_make_type (enum tree_code code) tree_node_sizes[(int)lang_type] += sizeof (struct lang_type); } } + return add; +} + +tree +cxx_make_type (enum tree_code code) +{ + tree t = make_node (code); + + maybe_add_lang_type_raw (t); /* Set up some flags that give proper default behavior. */ if (RECORD_OR_UNION_CODE_P (code)) |