mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-19 11:09:45 +08:00
cp-tree.def (FUNCTION_NAME): New tree node.
* cp-tree.def (FUNCTION_NAME): New tree node. * cp-tree.h (current_function_name_declared): Tweak documentation. (lang_decl_flags): Add pretty_function_p, adjust dummy. (DECL_PRETTY_FUNCTION_P): New macro. * decl.c (cp_finish_decl): Handle declarations of __FUNCTION__, etc., in a template function. Use at_function_scope_p instead of expanding it inline. * pt.c (tsubst_decl): Handle DECL_PRETTY_FUNCTION_P declarations specially. (tsubst): Handle FUNCTION_NAME. (tsubst_copy): Likewise. (instantiate_decl): Prevent redeclarations of __PRETTY_FUNCTION__, etc. in instantiation. * semantics.c (begin_compound_stmt): Declare __FUNCTION__, etc., even in template functions. (setup_vtbl_ptr): Don't declare __PRETTY_FUNCTION in the conditional scope at the top of a destructor. * error.c (dump_function_decl): Use `[ with ... ]' syntax for specializations too. From-SVN: r30625
This commit is contained in:
parent
a96c67ec89
commit
f981720185
@ -1,3 +1,26 @@
|
||||
1999-11-22 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* cp-tree.def (FUNCTION_NAME): New tree node.
|
||||
* cp-tree.h (current_function_name_declared): Tweak documentation.
|
||||
(lang_decl_flags): Add pretty_function_p, adjust dummy.
|
||||
(DECL_PRETTY_FUNCTION_P): New macro.
|
||||
* decl.c (cp_finish_decl): Handle declarations of __FUNCTION__,
|
||||
etc., in a template function. Use at_function_scope_p instead of
|
||||
expanding it inline.
|
||||
* pt.c (tsubst_decl): Handle DECL_PRETTY_FUNCTION_P declarations
|
||||
specially.
|
||||
(tsubst): Handle FUNCTION_NAME.
|
||||
(tsubst_copy): Likewise.
|
||||
(instantiate_decl): Prevent redeclarations of __PRETTY_FUNCTION__,
|
||||
etc. in instantiation.
|
||||
* semantics.c (begin_compound_stmt): Declare __FUNCTION__, etc.,
|
||||
even in template functions.
|
||||
(setup_vtbl_ptr): Don't declare __PRETTY_FUNCTION in the
|
||||
conditional scope at the top of a destructor.
|
||||
|
||||
* error.c (dump_function_decl): Use `[ with ... ]' syntax for
|
||||
specializations too.
|
||||
|
||||
1999-11-22 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
* semantics.c (finish_unary_op_expr): Only set TREE_NEGATED_INT
|
||||
|
@ -200,6 +200,9 @@ DEFTREECODE (SRCLOC, "srcloc", 'x', 2)
|
||||
unused. */
|
||||
DEFTREECODE (LOOKUP_EXPR, "lookup_expr", 'e', 1)
|
||||
|
||||
/* Used to represent __PRETTY_FUNCTION__ in template bodies. */
|
||||
DEFTREECODE (FUNCTION_NAME, "function_name", 'e', 0)
|
||||
|
||||
/* A whole bunch of tree codes for the initial, superficial parsing of
|
||||
templates. */
|
||||
DEFTREECODE (MODOP_EXPR, "modop_expr", 'e', 3)
|
||||
|
@ -789,8 +789,9 @@ struct language_function
|
||||
#define current_function_parms_stored \
|
||||
cp_function_chain->parms_stored
|
||||
|
||||
/* Non-zero if we have already declared __FUNCTION__ (and related
|
||||
variables) in the current function. */
|
||||
/* One if we have already declared __FUNCTION__ (and related
|
||||
variables) in the current function. Two if we are in the process
|
||||
of doing so. */
|
||||
|
||||
#define current_function_name_declared \
|
||||
cp_function_chain->name_declared
|
||||
@ -1607,7 +1608,8 @@ struct lang_decl_flags
|
||||
unsigned pending_inline_p : 1;
|
||||
unsigned global_ctor_p : 1;
|
||||
unsigned global_dtor_p : 1;
|
||||
unsigned dummy : 3;
|
||||
unsigned pretty_function_p : 1;
|
||||
unsigned dummy : 2;
|
||||
|
||||
tree context;
|
||||
|
||||
@ -1766,6 +1768,11 @@ struct lang_decl
|
||||
must be overridden by derived classes. */
|
||||
#define DECL_NEEDS_FINAL_OVERRIDER_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.needs_final_overrider)
|
||||
|
||||
/* Nonzero if this DECL is the __PRETTY_FUNCTION__ variable in a
|
||||
template function. */
|
||||
#define DECL_PRETTY_FUNCTION_P(NODE) \
|
||||
(DECL_LANG_SPECIFIC(NODE)->decl_flags.pretty_function_p)
|
||||
|
||||
/* The _TYPE context in which this _DECL appears. This field holds the
|
||||
class where a virtual function instance is actually defined, and the
|
||||
lexical scope of a friend function defined in a class body. */
|
||||
|
@ -7606,6 +7606,26 @@ 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 (current_function && 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);
|
||||
@ -7639,8 +7659,7 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
|
||||
return;
|
||||
|
||||
/* Add this declaration to the statement-tree. */
|
||||
if (building_stmt_tree ()
|
||||
&& TREE_CODE (current_scope ()) == FUNCTION_DECL)
|
||||
if (building_stmt_tree () && at_function_scope_p ())
|
||||
add_decl_stmt (decl);
|
||||
|
||||
if (TYPE_HAS_MUTABLE_P (type))
|
||||
|
@ -1112,7 +1112,7 @@ dump_function_decl (t, flags)
|
||||
t = DECL_TEMPLATE_RESULT (t);
|
||||
|
||||
/* Pretty print template instantiations only. */
|
||||
if (DECL_TEMPLATE_INSTANTIATION (t))
|
||||
if (DECL_USE_TEMPLATE (t) && DECL_TEMPLATE_INFO (t))
|
||||
{
|
||||
template_args = DECL_TI_ARGS (t);
|
||||
t = most_general_template (t);
|
||||
|
39
gcc/cp/pt.c
39
gcc/cp/pt.c
@ -5890,7 +5890,7 @@ tsubst_decl (t, args, type, in_decl)
|
||||
/* This declaration is going to have to be around for a while,
|
||||
so me make sure it is on a saveable obstack. */
|
||||
r = copy_node (t);
|
||||
|
||||
|
||||
TREE_TYPE (r) = type;
|
||||
c_apply_type_quals_to_decl (CP_TYPE_QUALS (type), r);
|
||||
DECL_CONTEXT (r) = ctx;
|
||||
@ -5903,6 +5903,16 @@ tsubst_decl (t, args, type, in_decl)
|
||||
copy_lang_decl (r);
|
||||
DECL_CLASS_CONTEXT (r) = DECL_CONTEXT (r);
|
||||
|
||||
/* For __PRETTY_FUNCTION__ we have to adjust the initializer. */
|
||||
if (DECL_PRETTY_FUNCTION_P (r))
|
||||
{
|
||||
DECL_INITIAL (r) = tsubst (DECL_INITIAL (t),
|
||||
args,
|
||||
/*complain=*/1,
|
||||
NULL_TREE);
|
||||
TREE_TYPE (r) = TREE_TYPE (DECL_INITIAL (r));
|
||||
}
|
||||
|
||||
/* Even if the original location is out of scope, the newly
|
||||
substituted one is not. */
|
||||
if (TREE_CODE (r) == VAR_DECL)
|
||||
@ -6676,6 +6686,24 @@ tsubst (t, args, complain, in_decl)
|
||||
return TREE_TYPE (e1);
|
||||
}
|
||||
|
||||
case FUNCTION_NAME:
|
||||
{
|
||||
const char *name;
|
||||
int len;
|
||||
tree type;
|
||||
tree str;
|
||||
|
||||
/* This code should match declare_hidden_char_array in
|
||||
c-common.c. */
|
||||
name = (*decl_printable_name) (current_function_decl, 2);
|
||||
len = strlen (name) + 1;
|
||||
type = build_array_type (char_type_node,
|
||||
build_index_type (build_int_2 (len, 0)));
|
||||
str = build_string (len, name);
|
||||
TREE_TYPE (str) = type;
|
||||
return str;
|
||||
}
|
||||
|
||||
default:
|
||||
sorry ("use of `%s' in template",
|
||||
tree_code_name [(int) TREE_CODE (t)]);
|
||||
@ -7035,7 +7063,10 @@ tsubst_copy (t, args, complain, in_decl)
|
||||
return build_va_arg (tsubst_copy (TREE_OPERAND (t, 0), args, complain,
|
||||
in_decl),
|
||||
tsubst (TREE_TYPE (t), args, complain, in_decl));
|
||||
|
||||
|
||||
case FUNCTION_NAME:
|
||||
return tsubst (t, args, complain, in_decl);
|
||||
|
||||
default:
|
||||
return t;
|
||||
}
|
||||
@ -9532,6 +9563,10 @@ instantiate_decl (d)
|
||||
start_function (NULL_TREE, d, NULL_TREE, SF_PRE_PARSED);
|
||||
store_parm_decls ();
|
||||
|
||||
/* We already set up __FUNCTION__, etc., so we don't want to do
|
||||
it again now. */
|
||||
current_function_name_declared = 1;
|
||||
|
||||
/* Substitute into the body of the function. */
|
||||
tsubst_expr (DECL_SAVED_TREE (code_pattern), args,
|
||||
/*complain=*/1, tmpl);
|
||||
|
@ -936,10 +936,14 @@ begin_compound_stmt (has_no_scope)
|
||||
variables __FUNCTION__, __PRETTY_FUNCTION__, and so forth. */
|
||||
if (current_function
|
||||
&& !current_function_name_declared
|
||||
&& !processing_template_decl
|
||||
&& !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;
|
||||
}
|
||||
|
||||
@ -1187,6 +1191,7 @@ setup_vtbl_ptr ()
|
||||
tree binfo = TYPE_BINFO (current_class_type);
|
||||
tree if_stmt;
|
||||
tree compound_stmt;
|
||||
int saved_cfnd;
|
||||
|
||||
/* If the dtor is empty, and we know there is not possible way we
|
||||
could use any vtable entries, before they are possibly set by
|
||||
@ -1202,11 +1207,17 @@ setup_vtbl_ptr ()
|
||||
/* If it is not safe to avoid setting up the vtables, then
|
||||
someone will change the condition to be boolean_true_node.
|
||||
(Actually, for now, we do not have code to set the condition
|
||||
appropriate, so we just assume that we always need to
|
||||
appropriately, so we just assume that we always need to
|
||||
initialize the vtables.) */
|
||||
finish_if_stmt_cond (boolean_true_node, if_stmt);
|
||||
current_vcalls_possible_p = &IF_COND (if_stmt);
|
||||
|
||||
/* Don't declare __PRETTY_FUNCTION__ and friends here when we
|
||||
open the block for the if-body. */
|
||||
saved_cfnd = current_function_name_declared;
|
||||
current_function_name_declared = 1;
|
||||
compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
|
||||
current_function_name_declared = saved_cfnd;
|
||||
|
||||
/* Make all virtual function table pointers in non-virtual base
|
||||
classes point to CURRENT_CLASS_TYPE's virtual function
|
||||
|
@ -3,8 +3,6 @@
|
||||
|
||||
// make sure __FUNCTION__ and __PRETTY_FUNCTION__ work in member functions
|
||||
|
||||
// execution test - XFAIL *-*-*
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -3,8 +3,6 @@
|
||||
|
||||
// make sure __FUNCTION__ and __PRETTY_FUNCTION__ work in templates
|
||||
|
||||
// execution test - XFAIL *-*-*
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -21,7 +19,7 @@ template<class T> void f1 (T)
|
||||
|
||||
if (strcmp (function, "f1"))
|
||||
bad = true;
|
||||
if (strcmp (pretty, "void f1<float> (float)")) // only for float instantiation
|
||||
if (strcmp (pretty, "void f1 (T) [with T = float]")) // only for float instantiation
|
||||
bad = true;
|
||||
}
|
||||
|
||||
@ -36,7 +34,7 @@ template<> void f1<int> (int)
|
||||
|
||||
if (strcmp (function, "f1"))
|
||||
bad = true;
|
||||
if (strcmp (pretty, "void f1<int> (int)"))
|
||||
if (strcmp (pretty, "void f1 (T) [with T = int]"))
|
||||
bad = true;
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ char* S3<char>::h(int) { return __PRETTY_FUNCTION__; }
|
||||
int main()
|
||||
{
|
||||
if (strcmp (S3<double>::h(7),
|
||||
"char *S3<double>::h<int> (int)") == 0)
|
||||
"char *S3<T>::h (U) [with U = int, T = double]") == 0)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
|
Loading…
Reference in New Issue
Block a user