aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl.c
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@gcc.gnu.org>2001-04-24 08:22:06 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2001-04-24 08:22:06 +0000
commit0ba8a114c724d36034e8996eefb7c94d4fe8aed0 (patch)
tree268353894884ce2459e1f3b08adc4825b8ed0dd6 /gcc/cp/decl.c
parentdfbb4f347cf43b955f56ecbc9709b8836d395ee5 (diff)
downloadgcc-0ba8a114c724d36034e8996eefb7c94d4fe8aed0.zip
gcc-0ba8a114c724d36034e8996eefb7c94d4fe8aed0.tar.gz
gcc-0ba8a114c724d36034e8996eefb7c94d4fe8aed0.tar.bz2
Lazy __FUNCTION__ generation.
gcc: Lazy __FUNCTION__ generation. * c-common.h (RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME, RID_C99_FUNCTION_NAME): New _RIDs. (CTI_FUNCTION_ID, CTI_PRETTY_FUNCTION_ID, CTI_FUNC_ID): Remove. (CTI_FUNCTION_NAME_DECL, CTI_PRETTY_FUNCTION_NAME_DECL, CTI_C99_FUNCTION_NAME_DECL, CTI_SAVED_FUNCTION_NAME_DECLS): New global tree slots. (function_id_node, pretty_function_id_node, func_id_node): Remove. (c99_function_name_decl_node, function_name_decl_node, pretty_function_name_decl_node, saved_function_name_decls): Declare. (struct language_function): Remove x_function_name_declared_p. (make_fname_decl): Remove a parameter. (declare_function_names): Remove prototype. (start_fname_decls, finish_fname_decls): Prototype. (fname_as_string): Likewise. (fname_string, fname_decl): Likewise. * c-common.c (make_fname_decl): Adjust. (struct fname_var_t): New struct. (fname_vars): New static array. (declare_function_name): Remove. (start_fname_decls, finish_fname_decls): New functions. (fname_as_string): New function from remnants of declare_function_name. (fname_string, fname_decl): New functions. * c-decl.c (c_function_name_declared_p): Remove. (init_decl_processing): Don't generate __FUNCTION__ et al ids, don't call declare_function_name. Call start_fname_decls. (c_make_fname_decl): Adjust parameters. Generate the name. Don't clobber the line number. Call finish_decl. (start_function): Call start_fname_decls. (finish_function): Call finish_fname_decls. Remove c_function_name_declared_p. (push_c_function_context): Don't push c_function_name_declared_p. (pop_c_function_context): Don't pop c_function_name_declared_p. (c_begin_compound_stmt): Don't check c_function_name_declared_p. * c-parse.in (STRING_FUNC_NAME, VAR_FUNC_NAME): New tokens. (program): Call finish_fname_decls for C. (primary): Add VAR_FUNC_NAME. (reswords): Add slots for __FUNCTION__ et al. (rid_to_yy): Add mappings for __FUNCTION__ et al. (yylexname): If it's a STRING_FUNC_NAME generate the function name now. Don't look for VAR_DECLs containing __FUNCTION__ et al. * c-semantics.c (prune_unused_decls): Remove. (finish_stmt_tree): Don't call prune_unused_decls. (genrtl_decl_stmt): Don't prune unused decls here. cp: Lazy __FUNCTION__ generation. * cp-tree.def (FUNCTION_NAME): Remove. * cp-tree.h (function_name_declared_p): Remove. (cp_fname_init): Prototype. * decl.c (init_decl_processing): Don't generate __FUNCTION__ et al ids, don't call declare_function_name. Call start_fname_decls. (cp_make_fname_decl): Adjust parameters. Generate the name. Don't clobber the line number. (cp_fname_init): New function. (start_function): Call start_fname_decls. (finish_function): Call finish_fname_decls. * lex.c (reswords): Add slots for __FUNCTION__ et al. (rid_to_yy): Add mappings for __FUNCTION__ et al. * optimize.c (maybe_clone_body): Remove function_name_declared_p. * parse.y (VAR_FUNC_NAME): New token. (primary): Add VAR_FUNC_NAME. * pt.c (tsubst_decl): Adjust a DECL_PRETTY_FUNCTION_P's generation. (tsubst, FUNCTION_NAME case): Remove. (tsubst_copy, FUNCTION_NAME case): Remove. (tsubst_expr, DECL_STMT case): Be careful with a DECL_PRETTY_FUNCTION_P. (instantiate_decl): Remove function_name_declared_p. * semantics.c (begin_compound_statement): Don't call declare_function_name here. (setup_vtbl_ptr). Don't save & restore function_name_declared_p. (finish_translation_unit): Call finish_fname_decls. (expand_body): Remove function_name_declared_p. * typeck2.c (digest_init): Allow any ERROR_MARK. testsuite: * gcc.dg/c99-func-2.c: Remove xfail. * gcc.dg/c99-func-3.c: Remove xfail. * gcc.dg/c99-func-4.c: Remove xfail. From-SVN: r41520
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r--gcc/cp/decl.c103
1 files changed, 58 insertions, 45 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 85a7310..834e2dc 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -138,7 +138,7 @@ static tree get_atexit_node PARAMS ((void));
static tree get_dso_handle_node PARAMS ((void));
static tree start_cleanup_fn PARAMS ((void));
static void end_cleanup_fn PARAMS ((void));
-static tree cp_make_fname_decl PARAMS ((tree, const char *, int));
+static tree cp_make_fname_decl PARAMS ((tree, int));
static void initialize_predefined_identifiers PARAMS ((void));
static tree check_special_function_return_type
PARAMS ((special_function_kind, tree, tree));
@@ -6519,6 +6519,7 @@ init_decl_processing ()
{
tree bad_alloc_type_node, newtype, deltype;
+
if (flag_honor_std)
push_namespace (std_identifier);
bad_alloc_type_node = xref_tag
@@ -6526,7 +6527,8 @@ init_decl_processing ()
if (flag_honor_std)
pop_namespace ();
newtype = build_exception_variant
- (ptr_ftype_sizetype, add_exception_specifier (NULL_TREE, bad_alloc_type_node, -1));
+ (ptr_ftype_sizetype, add_exception_specifier
+ (NULL_TREE, bad_alloc_type_node, -1));
deltype = build_exception_variant (void_ftype_ptr, empty_except_spec);
push_cp_library_fn (NEW_EXPR, newtype);
push_cp_library_fn (VEC_NEW_EXPR, newtype);
@@ -6553,13 +6555,8 @@ init_decl_processing ()
if (! supports_one_only ())
flag_weak = 0;
- /* Create the global bindings for __FUNCTION__ and __PRETTY_FUNCTION__. */
- function_id_node = get_identifier ("__FUNCTION__");
- pretty_function_id_node = get_identifier ("__PRETTY_FUNCTION__");
- func_id_node = get_identifier ("__func__");
-
make_fname_decl = cp_make_fname_decl;
- declare_function_name ();
+ start_fname_decls ();
/* Prepare to check format strings against argument lists. */
init_function_format_info ();
@@ -6607,57 +6604,68 @@ init_decl_processing ()
ggc_add_tree_root (&free_bindings, 1);
}
+/* Generate an initializer for a function naming variable from
+ NAME. NAME may be NULL, in which case we generate a special
+ ERROR_MARK node which should be replaced later. */
+
+tree
+cp_fname_init (name)
+ const char *name;
+{
+ tree domain = NULL_TREE;
+ tree type;
+ tree init = NULL_TREE;
+ size_t length = 0;
+
+ if (name)
+ {
+ length = strlen (name);
+ domain = build_index_type (size_int (length));
+ init = build_string (length + 1, name);
+ }
+
+ type = build_qualified_type (char_type_node, TYPE_QUAL_CONST);
+ type = build_cplus_array_type (type, domain);
+
+ if (init)
+ TREE_TYPE (init) = type;
+ else
+ /* We don't know the value until instantiation time. Make
+ something which will be digested now, but replaced later. */
+ init = build (ERROR_MARK, type);
+
+ return init;
+}
+
/* Create the VAR_DECL for __FUNCTION__ etc. ID is the name to give the
decl, NAME is the initialization string and TYPE_DEP indicates whether
NAME depended on the type of the function. We make use of that to detect
- __PRETTY_FUNCTION__ inside a template fn. Because we build a tree for
- the function before emitting any of it, we don't need to treat the
- VAR_DECL specially. We can decide whether to emit it later, if it was
- used. */
+ __PRETTY_FUNCTION__ inside a template fn. This is being done
+ lazily at the point of first use, so we musn't push the decl now. */
static tree
-cp_make_fname_decl (id, name, type_dep)
+cp_make_fname_decl (id, type_dep)
tree id;
- const char *name;
int type_dep;
{
- tree decl, type, init;
- size_t length = strlen (name);
- tree domain = NULL_TREE;
-
- if (!processing_template_decl)
- type_dep = 0;
- if (!type_dep)
- domain = build_index_type (size_int (length));
-
- type = build_cplus_array_type
- (build_qualified_type (char_type_node, TYPE_QUAL_CONST),
- domain);
+ const char *name = (type_dep && processing_template_decl
+ ? NULL : fname_as_string (type_dep));
+ tree init = cp_fname_init (name);
+ tree decl = build_decl (VAR_DECL, id, TREE_TYPE (init));
- decl = build_decl (VAR_DECL, id, type);
+ /* As we don't push the decl here, we must set the context. */
+ DECL_CONTEXT (decl) = current_function_decl;
+ DECL_PRETTY_FUNCTION_P (decl) = type_dep;
+
TREE_STATIC (decl) = 1;
TREE_READONLY (decl) = 1;
- DECL_SOURCE_LINE (decl) = 0;
DECL_ARTIFICIAL (decl) = 1;
- DECL_IN_SYSTEM_HEADER (decl) = 1;
- DECL_IGNORED_P (decl) = 1;
- pushdecl (decl);
- if (processing_template_decl)
- decl = push_template_decl (decl);
- if (type_dep)
- {
- init = build (FUNCTION_NAME, type);
- DECL_PRETTY_FUNCTION_P (decl) = 1;
- }
- else
- {
- init = build_string (length + 1, name);
- TREE_TYPE (init) = type;
- }
DECL_INITIAL (decl) = init;
- cp_finish_decl (decl, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
+
+ TREE_USED (decl) = 1;
- /* We will have to make sure we only emit this, if it is actually used. */
+ cp_finish_decl (decl, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
+
return decl;
}
@@ -12966,6 +12974,7 @@ finish_enum (enumtype)
if (scope && TREE_CODE (scope) == FUNCTION_DECL)
add_stmt (build_min (TAG_DEFN, enumtype));
+
return;
}
@@ -13602,6 +13611,8 @@ start_function (declspecs, declarator, attrs, flags)
DECL_CONTEXT (dtor_label) = current_function_decl;
}
+ start_fname_decls ();
+
store_parm_decls (current_function_parms);
return 1;
@@ -13931,6 +13942,8 @@ finish_function (flags)
my_friendly_assert (building_stmt_tree (), 20000911);
+ finish_fname_decls ();
+
/* For a cloned function, we've already got all the code we need;
there's no need to add any extra bits. */
if (!DECL_CLONED_FUNCTION_P (fndecl))