OSDN Git Service

* cp-tree.def (FUNCTION_NAME): New tree node.
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 23 Nov 1999 02:49:41 +0000 (02:49 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 23 Nov 1999 02:49:41 +0000 (02:49 +0000)
* 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

gcc/cp/ChangeLog
gcc/cp/cp-tree.def
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/error.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/testsuite/g++.old-deja/g++.ext/pretty2.C
gcc/testsuite/g++.old-deja/g++.ext/pretty3.C
gcc/testsuite/g++.old-deja/g++.pt/memtemp77.C

index c2f9d74..d214aaa 100644 (file)
@@ -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
index d8eb62f..de874cb 100644 (file)
@@ -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)
index 61a7686..44d16c6 100644 (file)
@@ -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. */
index 91b8552..adb3684 100644 (file)
@@ -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))
index 9151b8c..2b7b4ea 100644 (file)
@@ -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);
index 7e3a8ab..18307b3 100644 (file)
@@ -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);
index 741f710..37510e5 100644 (file)
@@ -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
index 14eb527..8f69bf4 100644 (file)
@@ -3,8 +3,6 @@
 
 // make sure __FUNCTION__ and __PRETTY_FUNCTION__ work in member functions
 
-// execution test - XFAIL *-*-*
-
 #include <stdio.h>
 #include <string.h>
 
index 148b3ba..820f08e 100644 (file)
@@ -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;
 }
 
index 54c4995..827e2df 100644 (file)
@@ -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;