mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-21 08:03:41 +08:00
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:
parent
8ce5ef1923
commit
2ce07e2d92
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
|
39
gcc/c-decl.c
39
gcc/c-decl.c
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user