aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/lex.c
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2017-05-31 16:46:58 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2017-05-31 16:46:58 +0000
commit91e920c9390f5293fdc84fbf9859dab53d7454b0 (patch)
tree4c41fc434e3fb47d6867bccb8b227635de1ff46b /gcc/cp/lex.c
parent3909991c7b89c99e28d4b8ed2a2de740adb1d432 (diff)
downloadgcc-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.c162
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))