c-common.h (make_fname_decl): Declare.

gcc:
	* c-common.h (make_fname_decl): Declare.
	* c-common.c (make_fname_decl): Define.
	(declare_hidden_char_array): Remove.
	(declare_function_name): Use make_fname_decl.
	* c-decl.c (c_make_fname_decl): New function.
	(init_decl_processing): Set make_fname_decl.

gcc/cp:
	* decl.c (cp_make_fname_decl): New function.
	(wrapup_globals_for_namespace): Don't emit unused static vars.
	(init_decl_processing): Remove comment about use of
	array_domain_type. Set make_fname_decl.
	(cp_finish_decl): Remove __FUNCTION__ nadgering.
	* semantics.c (begin_compound_stmt): Remove
	current_function_name_declared flagging.
	(expand_stmt): Don't emit unused local statics.
	* typeck.c (decay_conversion): Don't treat __FUNCTION__ decls
	specially.

From-SVN: r32418
This commit is contained in:
Nathan Sidwell 2000-03-08 11:21:28 +00:00 committed by Nathan Sidwell
parent 8ce5ef1923
commit 2ce07e2d92
8 changed files with 147 additions and 72 deletions

View File

@ -1,3 +1,12 @@
2000-03-08 Nathan Sidwell <nathan@codesourcery.com>
* c-common.h (make_fname_decl): Declare.
* c-common.c (make_fname_decl): Define.
(declare_hidden_char_array): Remove.
(declare_function_name): Use make_fname_decl.
* c-decl.c (c_make_fname_decl): New function.
(init_decl_processing): Set make_fname_decl.
Tue Mar 7 23:50:31 2000 Jeffrey A Law (law@cygnus.com)
* cccp.c (handle_directive): Initialize backslash_newlines_p.

View File

@ -135,6 +135,8 @@ enum cpp_token cpp_token;
tree c_global_trees[CTI_MAX];
tree (*make_fname_decl) PARAMS ((tree, const char *, int));
/* Nonzero means the expression being parsed will never be evaluated.
This is a count, since unevaluated expressions can nest. */
int skip_evaluation;
@ -148,7 +150,6 @@ enum attrs {A_PACKED, A_NOCOMMON, A_COMMON, A_NORETURN, A_CONST, A_T_UNION,
enum format_type { printf_format_type, scanf_format_type,
strftime_format_type };
static void declare_hidden_char_array PARAMS ((const char *, const char *));
static void add_attribute PARAMS ((enum attrs, const char *,
int, int, int));
static void init_attributes PARAMS ((void));
@ -269,42 +270,12 @@ declare_function_name ()
name = "";
printable_name = (*decl_printable_name) (current_function_decl, 2);
}
declare_hidden_char_array ("__FUNCTION__", name);
declare_hidden_char_array ("__PRETTY_FUNCTION__", printable_name);
(*make_fname_decl) (get_identifier ("__FUNCTION__"), name, 0);
(*make_fname_decl) (get_identifier ("__PRETTY_FUNCTION__"), printable_name, 1);
/* The ISO C people "of course" couldn't use __FUNCTION__ in the
ISO C 99 standard; instead a new variable is invented. */
declare_hidden_char_array ("__func__", name);
}
static void
declare_hidden_char_array (name, value)
const char *name, *value;
{
tree decl, type, init;
unsigned int vlen;
/* If the default size of char arrays isn't big enough for the name,
or if we want to give warnings for large objects, make a bigger one. */
vlen = strlen (value) + 1;
type = char_array_type_node;
if (compare_tree_int (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), vlen) < 0
|| warn_larger_than)
type = build_array_type (char_type_node,
build_index_type (build_int_2 (vlen, 0)));
decl = build_decl (VAR_DECL, get_identifier (name), type);
TREE_STATIC (decl) = 1;
TREE_READONLY (decl) = 1;
TREE_ASM_WRITTEN (decl) = 1;
DECL_SOURCE_LINE (decl) = 0;
DECL_ARTIFICIAL (decl) = 1;
DECL_IN_SYSTEM_HEADER (decl) = 1;
DECL_IGNORED_P (decl) = 1;
init = build_string (vlen, value);
TREE_TYPE (init) = type;
DECL_INITIAL (decl) = init;
finish_decl (pushdecl (decl), init, NULL_TREE);
(*make_fname_decl) (get_identifier ("__func__"), name, 0);
}
/* Given a chain of STRING_CST nodes,

View File

@ -74,6 +74,13 @@ extern tree c_global_trees[CTI_MAX];
#define int_ftype_int c_global_trees[CTI_INT_FTYPE_INT]
#define ptr_ftype_sizetype c_global_trees[CTI_PTR_FTYPE_SIZETYPE]
/* Pointer to function to generate the VAR_DECL for __FUNCTION__ etc.
ID is the identifier to use, NAME is the string.
TYPE_DEP indicates whether it depends on type of the function or not
(i.e. __PRETTY_FUNCTION__). */
extern tree (*make_fname_decl) PARAMS ((tree, const char *, int));
extern void declare_function_name PARAMS ((void));
extern void decl_attributes PARAMS ((tree, tree, tree));
extern void init_function_format_info PARAMS ((void));

View File

@ -288,6 +288,7 @@ static tree grokdeclarator PARAMS ((tree, tree, enum decl_context,
int));
static tree grokparms PARAMS ((tree, int));
static void layout_array_type PARAMS ((tree));
static tree c_make_fname_decl PARAMS ((tree, const char *, int));
/* C-specific option variables. */
@ -3059,6 +3060,7 @@ init_decl_processing ()
pedantic_lvalues = pedantic;
/* Create the global bindings for __FUNCTION__ and __PRETTY_FUNCTION__. */
make_fname_decl = c_make_fname_decl;
declare_function_name ();
start_identifier_warnings ();
@ -3085,6 +3087,43 @@ init_decl_processing ()
ggc_add_tree_root (&static_dtors, 1);
}
/* 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. As we don't yet implement
delayed emission of static data, we mark the decl as emitted
so it is not placed in the output. Anything using it must therefore pull
out the STRING_CST initializer directly. This does mean that these names
are string merging candidates, which C99 does not permit. */
static tree
c_make_fname_decl (id, name, type_dep)
tree id;
const char *name;
int type_dep ATTRIBUTE_UNUSED;
{
tree decl, type, init;
size_t length = strlen (name);
type = build_array_type
(build_qualified_type (char_type_node, TYPE_QUAL_CONST),
build_index_type (build_int_2 (length, 0)));
decl = build_decl (VAR_DECL, id, type);
TREE_STATIC (decl) = 1;
TREE_READONLY (decl) = 1;
TREE_ASM_WRITTEN (decl) = 1;
DECL_SOURCE_LINE (decl) = 0;
DECL_ARTIFICIAL (decl) = 1;
DECL_IN_SYSTEM_HEADER (decl) = 1;
DECL_IGNORED_P (decl) = 1;
init = build_string (length + 1, name);
TREE_TYPE (init) = type;
DECL_INITIAL (decl) = init;
finish_decl (pushdecl (decl), init, NULL_TREE);
return decl;
}
/* Return a definition for a builtin function named NAME and whose data type
is TYPE. TYPE should be a function type with argument types.
FUNCTION_CODE tells later passes how to compile calls to this function.

View File

@ -1,3 +1,16 @@
2000-03-08 Nathan Sidwell <nathan@codesourcery.com>
* decl.c (cp_make_fname_decl): New function.
(wrapup_globals_for_namespace): Don't emit unused static vars.
(init_decl_processing): Remove comment about use of
array_domain_type. Set make_fname_decl.
(cp_finish_decl): Remove __FUNCTION__ nadgering.
* semantics.c (begin_compound_stmt): Remove
current_function_name_declared flagging.
(expand_stmt): Don't emit unused local statics.
* typeck.c (decay_conversion): Don't treat __FUNCTION__ decls
specially.
2000-03-08 Nathan Sidwell <nathan@codesourcery.com>
* typeck.c (convert_for_assignment): Don't look at array

View File

@ -182,6 +182,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));
#if defined (DEBUG_CP_BINDING_LEVELS)
static void indent PARAMS ((void));
@ -1784,7 +1785,15 @@ wrapup_globals_for_namespace (namespace, data)
Put them into VEC from back to front, then take out from front. */
for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl))
vec[len - i - 1] = decl;
{
/* Pretend we've output an unused static variable. This ensures
that the toplevel __FUNCTION__ etc won't be emitted, unless
needed. */
if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
&& !TREE_USED (decl))
TREE_ASM_WRITTEN (decl) = 1;
vec[len - i - 1] = decl;
}
if (last_time)
{
@ -6168,9 +6177,7 @@ init_decl_processing ()
/* Make a type to be the domain of a few array types
whose domains don't really matter.
200 is small enough that it always fits in size_t
and large enough that it can hold most function names for the
initializations of __FUNCTION__ and __PRETTY_FUNCTION__. */
200 is small enough that it always fits in size_t. */
array_domain_type = build_index_type (build_int_2 (200, 0));
/* Make a type for arrays of characters.
@ -6340,6 +6347,7 @@ init_decl_processing ()
flag_weak = 0;
/* Create the global bindings for __FUNCTION__ and __PRETTY_FUNCTION__. */
make_fname_decl = cp_make_fname_decl;
declare_function_name ();
/* Prepare to check format strings against argument lists. */
@ -6390,6 +6398,59 @@ init_decl_processing ()
ggc_add_tree_root (&static_aggregates, 1);
}
/* 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. */
static tree
cp_make_fname_decl (id, name, 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 (build_int_2 (length, 0));
type = build_cplus_array_type
(build_qualified_type (char_type_node, TYPE_QUAL_CONST),
domain);
decl = build_lang_decl (VAR_DECL, id, type);
TREE_STATIC (decl) = 1;
TREE_READONLY (decl) = 1;
DECL_SOURCE_LINE (decl) = 0;
DECL_ARTIFICIAL (decl) = 1;
DECL_IN_SYSTEM_HEADER (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);
/* We will have to make sure we only emit this, if it is actually used. */
return decl;
}
/* Function to print any language-specific context for an error message. */
static void
@ -7627,26 +7688,6 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
return;
}
/* Handling __FUNCTION__ and its ilk in a template-function requires
some special processing because we are called from
language-independent code. */
if (cfun && processing_template_decl
&& current_function_name_declared == 2)
{
/* Since we're in a template function, we need to
push_template_decl. The language-independent code in
declare_hidden_char_array doesn't know to do this. */
retrofit_lang_decl (decl);
decl = push_template_decl (decl);
if (strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)),
"__PRETTY_FUNCTION__") == 0)
{
init = build (FUNCTION_NAME, const_string_type_node);
DECL_PRETTY_FUNCTION_P (decl) = 1;
}
}
/* If a name was specified, get the string. */
if (asmspec_tree)
asmspec = TREE_STRING_POINTER (asmspec_tree);

View File

@ -980,13 +980,8 @@ begin_compound_stmt (has_no_scope)
&& !current_function_name_declared
&& !has_no_scope)
{
/* When we get callbacks from the middle-end, we need to know
we're in the midst of declaring these variables. */
current_function_name_declared = 2;
/* Actually insert the declarations. */
declare_function_name ();
/* And now just remember that we're all done. */
current_function_name_declared = 1;
declare_function_name ();
}
return r;
@ -2397,7 +2392,11 @@ expand_stmt (t)
expand_anon_union_decl (decl, NULL_TREE,
DECL_ANON_UNION_ELEMS (decl));
}
else if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
else if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
&& TREE_USED (decl))
/* Do not emit unused decls. This is not just an
optimization. We really do not want to emit
__PRETTY_FUNCTION__ etc, if they're never used. */
make_rtl_for_local_static (decl);
}
break;

View File

@ -1716,12 +1716,8 @@ decay_conversion (exp)
/* Replace a nonvolatile const static variable with its value. We
don't do this for arrays, though; we want the address of the
first element of the array, not the address of the first element
of its initializing constant. We *do* replace variables that the
user isn't really supposed to know about; this is a hack to deal
with __PRETTY_FUNCTION__ and the like. */
else if (TREE_READONLY_DECL_P (exp)
&& (code != ARRAY_TYPE
|| (TREE_CODE (exp) == VAR_DECL && DECL_IGNORED_P (exp))))
of its initializing constant. */
else if (TREE_READONLY_DECL_P (exp) && code != ARRAY_TYPE)
{
exp = decl_constant_value (exp);
type = TREE_TYPE (exp);