summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>1999-11-23 02:49:41 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>1999-11-23 02:49:41 +0000
commitb0944a40432646aef47109d5cf01e22512355f3e (patch)
tree226ba8a834310f6b3389722c4c998ad288f65546
parentc90bf86c4c2d2f220539f0c8764c58ff8e15bbc5 (diff)
downloadgcc-b0944a40432646aef47109d5cf01e22512355f3e.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@30625 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog23
-rw-r--r--gcc/cp/cp-tree.def3
-rw-r--r--gcc/cp/cp-tree.h13
-rw-r--r--gcc/cp/decl.c23
-rw-r--r--gcc/cp/error.c2
-rw-r--r--gcc/cp/pt.c39
-rw-r--r--gcc/cp/semantics.c15
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ext/pretty2.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ext/pretty3.C6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/memtemp77.C2
10 files changed, 111 insertions, 17 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c2f9d741492..d214aaa0e86 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index d8eb62f65a5..de874cbd87a 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -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)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 61a76868473..44d16c6b1a1 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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. */
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 91b8552d54b..adb3684f4ae 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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))
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 9151b8c604e..2b7b4eae3dc 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -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);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 7e3a8abd088..18307b3e9aa 100644
--- a/gcc/cp/pt.c
+++ b/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);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 741f710800a..37510e5e7fa 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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
diff --git a/gcc/testsuite/g++.old-deja/g++.ext/pretty2.C b/gcc/testsuite/g++.old-deja/g++.ext/pretty2.C
index 14eb5276ef5..8f69bf4b50f 100644
--- a/gcc/testsuite/g++.old-deja/g++.ext/pretty2.C
+++ b/gcc/testsuite/g++.old-deja/g++.ext/pretty2.C
@@ -3,8 +3,6 @@
// make sure __FUNCTION__ and __PRETTY_FUNCTION__ work in member functions
-// execution test - XFAIL *-*-*
-
#include <stdio.h>
#include <string.h>
diff --git a/gcc/testsuite/g++.old-deja/g++.ext/pretty3.C b/gcc/testsuite/g++.old-deja/g++.ext/pretty3.C
index 148b3badd6f..820f08e6f5e 100644
--- a/gcc/testsuite/g++.old-deja/g++.ext/pretty3.C
+++ b/gcc/testsuite/g++.old-deja/g++.ext/pretty3.C
@@ -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;
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memtemp77.C b/gcc/testsuite/g++.old-deja/g++.pt/memtemp77.C
index 54c49952dd7..827e2df71c8 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/memtemp77.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/memtemp77.C
@@ -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;