This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

RFC: Lazy __FUNCTION__ etc


This patch causes us to allocate the strings for __FUNCTION__,
__PRETTY_FUNCTION__, and __func__ lazily.  At present they are
allocated for every function when we enter it, then thrown away again
in the vast majority of functions that do not use them.  Or rather,
they don't get thrown away, because string constants are not garbage
collected... they just waste memory.

The new approach is to treat them as keywords which magically get
replaced with an appropriate string constant.  This produces the same
semantics as the old code (but see below), and does not require us to
allocate and deallocate them for every function.  In addition a fair
amount of ugly hack to prevent the strings from being emitted when
they're not used, goes away.  There may be more gunk that can now go
away; for instance, C++'s prune_unused_decls is now arguably doing
nothing useful.

We still get the semantics of __func__ wrong, but they are no more
wrong than they were before.  I believe I know how to correct __func__
within the new framework, and will attempt that after this patch goes in.

The patch is not quite ready for inclusion, because it somehow breaks
C++'s ext/pretty3.C and ext/pretty4.C tests.  I believe pretty4 is in
error: it wants __FUNCTION__ to be a different object from a string
constant with the same contents, and a different object for two
(overloaded) functions with the same base name.  This has never been
true in the C compiler, but apparently used to be true for C++.  I
would just change the test to match, but it's all templates and I
don't know how to hack it up properly.

pretty3, on the other hand, is a genuine problem.  We've got a generic
template function, and an explicit specialization.  Then main calls
the explicit specialization, and the generic version (causing an
implicit specialization).  Formerly, __PRETTY_FUNCTION__ was not
evaluated for template functions until they were specialized, so both
of them came out like "f1(T) [with T = float]".  Now
__PRETTY_FUNCTION__ is evaluated immediately, so the generic is just
called "f1(T)".  This is undesired.  I do not know why it happened or
how to put the semantics back the way they were - I do see some code
aimed at evaluating _P_F_ at template specialization time, in pt.c,
but I have no idea how we get there...

So I'm throwing the patch out for reactions and hopefully fixes.

zw


	* c-common.c (make_fname_decl, declare_function_name): Delete.
	(cfun_name_as_string): New function.
	* c-common.h (RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME,
	RID_C99_FUNCTION_NAME): Add to enum rid.
	(CTI_FUNCTION_ID, CTI_PRETTY_FUNCTION_ID, CTI_FUNC_ID,
	function_id_node, pretty_function_id_node, func_id_node,
	x_function_name_declared_p, make_fname_decl prototype,
	declare_function_name prototype): Kill.
	(cfun_name_as_string): Prototype.

	* c-parse.in (FUNC_NAME): New dummy token type.
	(reswords): Add __FUNCTION__, __PRETTY_FUNCTION__, and __func__.
	(rid_to_yy): Map RID_*FUNCTION_NAME to FUNC_NAME.
	(yylexname): If rid_to_yy lists FUNC_NAME as the yacc code,
	set yylval.ttype to the result of cfun_name_as_string, set
	last_token to CPP_STRING, and return STRING.  Delete code
	handling user-invisible read-only initialized variables, which
	don't happen anymore.

	* c-decl.c (c_function_name_declared_p): Kill variable and all
	references.
	(c_make_fname_decl): Delete function.
	(init_decl_processing): Do not set up *_id_node or
	make_fname_decl hook, or call declare_function_name.
	(c_begin_compound_stmt): Do not call declare_function_name.

cp:
	* cp-tree.h: Kill function_name_declared_p.
	* decl.c: Kill cp_make_fname_decl.
	(init_decl_processing): Do not set up *_id_node or
	make_fname_decl hook, or call declare_function_name.
	* optimize.c, pt.c, semantics.c: Remove references to
	function_name_declared_p.
	* semantics.c (begin_compound_stmt): Don't call
	declare_function_name.

	* lex.c (reswords): Add __FUNCTION__, __PRETTY_FUNCTION__, and
	__func__.
	(rid_to_yy): Add zeroes for RID_*FUNCTION_NAME.
	* spew.c (read_process_identifier): For RID_*FUNCTION_NAME,
	set pyylval->ttype to the result of cfun_name_as_string, and
	return STRING.


===================================================================
Index: c-common.c
--- c-common.c	2001/02/28 01:25:41	1.228
+++ c-common.c	2001/03/21 03:52:38
@@ -204,8 +204,6 @@ int warn_sequence_point;
    type names and storage classes.  It is indexed by a RID_... value.  */
 tree *ridpointers;
 
-tree (*make_fname_decl)                PARAMS ((tree, const char *, int));
-
 /* If non-NULL, the address of a language-specific function that
    returns 1 for language-specific statement codes.  */
 int (*lang_statement_code_p)           PARAMS ((enum tree_code));
@@ -343,35 +341,45 @@ c_finish_else ()
   tree if_stmt = if_stack[if_stack_pointer - 1].if_stmt;
   RECHAIN_STMTS (if_stmt, ELSE_CLAUSE (if_stmt));
 }
-
-/* Make bindings for __FUNCTION__, __PRETTY_FUNCTION__, and __func__.  */
 
-void
-declare_function_name ()
+/* Convert __FUNCTION__, __PRETTY_FUNCTION__, and __func__ to their
+   corresponding string constants.  This does not get the semantics of
+   __func__ right, but the difference is not likely to be noticed in
+   real code.  (__func__ is an implicitly declared static const
+   char [], not a string constant.  See C99 6.4.2.2.)  */
+tree
+cfun_name_as_string (rid_code)
+     enum rid rid_code;
 {
-  const char *name, *printable_name;
+  tree fdecl = current_function_decl;
 
-  if (current_function_decl == NULL)
-    {
-      name = "";
-      printable_name = "top level";
-    }
-  else
+  switch (rid_code)
     {
+    case RID_C99_FUNCTION_NAME:
+      if (fdecl == 0)
+	error ("__func__ may not be used at top level");
+
+      /* fall through */
+    case RID_FUNCTION_NAME:
       /* Allow functions to be nameless (such as artificial ones).  */
-      if (DECL_NAME (current_function_decl))
-        name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
+      if (fdecl && DECL_NAME (fdecl))
+	return build_string (IDENTIFIER_LENGTH (DECL_NAME (fdecl)) + 1,
+			     IDENTIFIER_POINTER (DECL_NAME (fdecl)));
+      else
+	return build_string (1, "");
+
+    case RID_PRETTY_FUNCTION_NAME:
+      if (fdecl)
+	{
+	  const char *name = (*decl_printable_name) (fdecl, 2);
+	  return build_string (strlen (name) + 1, name);
+	}
       else
-	name = "";
-      printable_name = (*decl_printable_name) (current_function_decl, 2);
+	return build_string (sizeof("top level") - 1, "top level");
 
-      /* ISO C99 defines __func__, which is a variable, not a string
-	 constant, and which is not a defined symbol at file scope.  */
-      (*make_fname_decl) (func_id_node, name, 0);
+    default:
+      abort ();
     }
-  
-  (*make_fname_decl) (function_id_node, name, 0);
-  (*make_fname_decl) (pretty_function_id_node, printable_name, 1);
 }
 
 /* Given a chain of STRING_CST nodes,
===================================================================
Index: c-common.h
--- c-common.h	2001/01/13 23:29:57	1.64
+++ c-common.h	2001/03/21 03:52:38
@@ -75,6 +75,9 @@ enum rid
   RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL,      RID_PTRBASE,
   RID_PTREXTENT, RID_PTRVALUE,
 
+  /* Too many ways of getting the name of a function as a string */
+  RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME, RID_C99_FUNCTION_NAME,
+
   /* C++ */
   RID_BOOL,     RID_WCHAR,    RID_CLASS,
   RID_PUBLIC,   RID_PRIVATE,  RID_PROTECTED,
@@ -154,11 +157,6 @@ enum c_tree_index
     CTI_G77_LONGINT_TYPE,
     CTI_G77_ULONGINT_TYPE,
 
-    /* These are not types, but we have to look them up all the time.  */
-    CTI_FUNCTION_ID,
-    CTI_PRETTY_FUNCTION_ID,
-    CTI_FUNC_ID,
-
     CTI_VOID_ZERO,
 
     CTI_MAX
@@ -202,10 +200,6 @@ enum c_tree_index
 #define g77_longint_type_node		c_global_trees[CTI_G77_LONGINT_TYPE]
 #define g77_ulongint_type_node		c_global_trees[CTI_G77_ULONGINT_TYPE]
 
-#define function_id_node		c_global_trees[CTI_FUNCTION_ID]
-#define pretty_function_id_node		c_global_trees[CTI_PRETTY_FUNCTION_ID]
-#define func_id_node			c_global_trees[CTI_FUNC_ID]
-
 /* A node for `((void) 0)'.  */
 #define void_zero_node                  c_global_trees[CTI_VOID_ZERO]
 
@@ -260,9 +254,6 @@ struct language_function {
   struct stmt_tree_s x_stmt_tree;
   /* The stack of SCOPE_STMTs for the current function.  */
   tree x_scope_stmt_stack;
-  /* Nonzero if __FUNCTION__ and its ilk have been declared in this
-     function.  */
-  int x_function_name_declared_p;
 };
 
 /* When building a statement-tree, this is the last statement added to
@@ -461,19 +452,12 @@ extern int warn_long_long;
    what operator was specified for it.  */
 #define C_EXP_ORIGINAL_CODE(exp) ((enum tree_code) TREE_COMPLEXITY (exp))
 
-/* 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 tree identifier_global_value		PARAMS ((tree));
 extern void record_builtin_type			PARAMS ((enum rid,
 							 const char *, tree));
 extern tree build_void_list_node		PARAMS ((void));
 
-extern void declare_function_name		PARAMS ((void));
+extern tree cfun_name_as_string			PARAMS ((enum rid));
 extern void decl_attributes			PARAMS ((tree, tree, tree));
 extern void init_function_format_info		PARAMS ((void));
 extern void check_function_format		PARAMS ((int *, tree, tree, tree));
===================================================================
Index: c-decl.c
--- c-decl.c	2001/03/19 23:49:50	1.215
+++ c-decl.c	2001/03/21 03:52:38
@@ -104,11 +104,6 @@ static struct stmt_tree_s c_stmt_tree;
 
 static tree c_scope_stmt_stack;
 
-/* Nonzero if __FUNCTION__ and its ilk have been declared in this
-   function.  */
-
-static int c_function_name_declared_p;
-
 /* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
    that have names.  Here so we can clear out their names' definitions
    at the end of the function.  */
@@ -279,7 +274,6 @@ static tree grokdeclarator		PARAMS ((tre
 						 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));
 static void c_expand_body               PARAMS ((tree, int));
 
 /* C-specific option variables.  */
@@ -3094,14 +3088,6 @@ init_decl_processing ()
 
   pedantic_lvalues = pedantic;
 
-  /* Create the global bindings for __FUNCTION__, __PRETTY_FUNCTION__,
-     and __func__.  */
-  function_id_node = get_identifier ("__FUNCTION__");
-  pretty_function_id_node = get_identifier ("__PRETTY_FUNCTION__");
-  func_id_node = get_identifier ("__func__");
-  make_fname_decl = c_make_fname_decl;
-  declare_function_name ();
-
   start_identifier_warnings ();
 
   /* Prepare to check format strings against argument lists.  */
@@ -3124,43 +3110,6 @@ 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 is wrong for C99's __func__.  FIXME.  */
-
-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.
@@ -6675,7 +6624,6 @@ finish_function (nested)
 	 function.  For a nested function, this value is used in
 	 pop_c_function_context and then reset via pop_function_context.  */
       current_function_decl = NULL;
-      c_function_name_declared_p = 0;
     }
 }
 
@@ -6917,7 +6865,6 @@ push_c_function_context (f)
 
   p->base.x_stmt_tree = c_stmt_tree;
   p->base.x_scope_stmt_stack = c_scope_stmt_stack;
-  p->base.x_function_name_declared_p = c_function_name_declared_p;
   p->named_labels = named_labels;
   p->shadowed_labels = shadowed_labels;
   p->returns_value = current_function_returns_value;
@@ -6955,7 +6902,6 @@ pop_c_function_context (f)
 
   c_stmt_tree = p->base.x_stmt_tree;
   c_scope_stmt_stack = p->base.x_scope_stmt_stack;
-  c_function_name_declared_p = p->base.x_function_name_declared_p;
   named_labels = p->named_labels;
   shadowed_labels = p->shadowed_labels;
   current_function_returns_value = p->returns_value;
@@ -7084,19 +7030,7 @@ extract_interface_info ()
 tree
 c_begin_compound_stmt ()
 {
-  tree stmt;
-
-  /* Create the COMPOUND_STMT.  */
-  stmt = add_stmt (build_stmt (COMPOUND_STMT, NULL_TREE));
-  /* If we haven't already declared __FUNCTION__ and its ilk then this
-     is the opening curly brace of the function.  Declare them now.  */
-  if (!c_function_name_declared_p)
-    {
-      c_function_name_declared_p = 1;
-      declare_function_name ();
-    }
-
-  return stmt;
+  return add_stmt (build_stmt (COMPOUND_STMT, NULL_TREE));
 }
 
 /* Expand T (a DECL_STMT) if it declares an entity not handled by the
===================================================================
Index: c-parse.in
--- c-parse.in	2001/03/07 01:31:59	1.84
+++ c-parse.in	2001/03/21 03:52:40
@@ -124,6 +124,9 @@ end ifc
 %token REALPART IMAGPART VA_ARG
 %token PTR_VALUE PTR_BASE PTR_EXTENT
 
+/* not used in the grammar, but to make life easier in yylexname */
+%token FUNC_NAME
+
 /* Add precedence rules to solve dangling else s/r conflict */
 %nonassoc IF
 %nonassoc ELSE
@@ -2884,6 +2887,8 @@ static const struct resword reswords[] =
 {
   { "_Bool",		RID_BOOL,	0 },
   { "_Complex",		RID_COMPLEX,	0 },
+  { "__FUNCTION__",	RID_FUNCTION_NAME, 0 },
+  { "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 },
   { "__alignof",	RID_ALIGNOF,	0 },
   { "__alignof__",	RID_ALIGNOF,	0 },
   { "__asm",		RID_ASM,	0 },
@@ -2898,6 +2903,7 @@ static const struct resword reswords[] =
   { "__const",		RID_CONST,	0 },
   { "__const__",	RID_CONST,	0 },
   { "__extension__",	RID_EXTENSION,	0 },
+  { "__func__",		RID_C99_FUNCTION_NAME, 0 },
   { "__imag",		RID_IMAGPART,	0 },
   { "__imag__",		RID_IMAGPART,	0 },
   { "__inline",		RID_INLINE,	0 },
@@ -3057,6 +3063,10 @@ static const short rid_to_yy[RID_MAX] =
   /* RID_PTREXTENT */	PTR_EXTENT,
   /* RID_PTRVALUE */	PTR_VALUE,
 
+  /* RID_FUNCTION_NAME */		FUNC_NAME,
+  /* RID_PRETTY_FUNCTION_NAME */	FUNC_NAME,
+  /* RID_C99_FUNCTION_NAME */		FUNC_NAME,
+
   /* C++ */
   /* RID_BOOL */	TYPESPEC,
   /* RID_WCHAR */	0,
@@ -3226,9 +3236,21 @@ yylexname ()
   if (C_IS_RESERVED_WORD (yylval.ttype))
     {
       enum rid rid_code = C_RID_CODE (yylval.ttype);
-      /* Return the canonical spelling for this keyword.  */
-      yylval.ttype = ridpointers[(int) rid_code];
-      return rid_to_yy[(int) rid_code];
+      int yycode = rid_to_yy[(int) rid_code];
+
+      if (yycode != FUNC_NAME) /* normal case */
+	{
+	  /* Return the canonical spelling for this keyword.  */
+	  yylval.ttype = ridpointers[(int) rid_code];
+	  return yycode;
+	}
+
+      /* __FUNCTION__, __PRETTY_FUNCTION__, and __func__ get converted
+	 to string constants.  Not quite right for __func__, but close
+	 enough for everything but a conformance suite. */
+      yylval.ttype = cfun_name_as_string (rid_code);
+      last_token = CPP_STRING;  /* so yyerror won't choke */
+      return STRING;
     }
 
   decl = lookup_name (yylval.ttype);
@@ -3236,23 +3258,6 @@ yylexname ()
     {
       if (TREE_CODE (decl) == TYPE_DECL)
 	return TYPENAME;
-      /* A user-invisible read-only initialized variable
-	 should be replaced by its value.
-	 We handle only strings since that's the only case used in C.  */
-      else if (TREE_CODE (decl) == VAR_DECL
-	       && DECL_IGNORED_P (decl)
-	       && TREE_READONLY (decl)
-	       && DECL_INITIAL (decl) != 0
-	       && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST)
-	{
-	  tree stringval = DECL_INITIAL (decl);
-
-	  /* Copy the string value so that we won't clobber anything
-	     if we put something in the TREE_CHAIN of this one.  */
-	  yylval.ttype = build_string (TREE_STRING_LENGTH (stringval),
-				       TREE_STRING_POINTER (stringval));
-	  return STRING;
-	}
     }
   else if (doing_objc_thang)
     {
===================================================================
Index: cp/cp-tree.h
--- cp/cp-tree.h	2001/03/19 23:49:53	1.586
+++ cp/cp-tree.h	2001/03/21 03:52:41
@@ -966,12 +966,6 @@ struct cp_language_function
 
 #define in_function_try_handler cp_function_chain->in_function_try_handler
 
-/* Nonzero if __FUNCTION__ and its ilk have been declared in this
-   function.  */
-
-#define function_name_declared_p \
-  (cp_function_chain->base.x_function_name_declared_p)
-
 extern tree current_function_return_value;
 extern tree global_namespace;
 
===================================================================
Index: cp/decl.c
--- cp/decl.c	2001/03/19 23:49:53	1.759
+++ cp/decl.c	2001/03/21 03:52:43
@@ -142,7 +142,6 @@ static tree get_atexit_node PARAMS ((voi
 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));
 static void initialize_predefined_identifiers PARAMS ((void));
 static tree check_special_function_return_type
   PARAMS ((special_function_kind, tree, tree));
@@ -6500,14 +6499,6 @@ init_decl_processing ()
   if (! supports_one_only ())
     flag_weak = 0;
 
-  /* Create the global bindings for __FUNCTION__ and __PRETTY_FUNCTION__.  */
-  function_id_node = get_identifier ("__FUNCTION__");
-  pretty_function_id_node = get_identifier ("__PRETTY_FUNCTION__");
-  func_id_node = get_identifier ("__func__");
-
-  make_fname_decl = cp_make_fname_decl;
-  declare_function_name ();
-
   /* Prepare to check format strings against argument lists.  */
   init_function_format_info ();
 
@@ -6554,59 +6545,6 @@ init_decl_processing ()
   ggc_add_tree_root (&free_bindings, 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 (size_int (length));
-
-  type =  build_cplus_array_type
-          (build_qualified_type (char_type_node, TYPE_QUAL_CONST),
-	   domain);
-
-  decl = build_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;
-  DECL_IGNORED_P (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;
-}
 
 /* Entry point for the benefit of c_common_nodes_and_builtins.
 
===================================================================
Index: cp/lex.c
--- cp/lex.c	2001/03/10 16:33:57	1.238
+++ cp/lex.c	2001/03/21 03:52:43
@@ -402,6 +402,8 @@ CONSTRAINT(ridbits_fit, RID_LAST_MODIFIE
 static const struct resword reswords[] =
 {
   { "_Complex",		RID_COMPLEX,	0 },
+  { "__FUNCTION__",	RID_FUNCTION_NAME, 0 },
+  { "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 },
   { "__alignof", 	RID_ALIGNOF,	0 },
   { "__alignof__",	RID_ALIGNOF,	0 },
   { "__asm",		RID_ASM,	0 },
@@ -414,6 +416,7 @@ static const struct resword reswords[] =
   { "__const",		RID_CONST,	0 },
   { "__const__",	RID_CONST,	0 },
   { "__extension__",	RID_EXTENSION,	0 },
+  { "__func__",		RID_C99_FUNCTION_NAME, 0 },
   { "__imag",		RID_IMAGPART,	0 },
   { "__imag__",		RID_IMAGPART,	0 },
   { "__inline",		RID_INLINE,	0 },
@@ -584,6 +587,11 @@ const short rid_to_yy[RID_MAX] =
   /* RID_PTRBASE */	0,
   /* RID_PTREXTENT */	0,
   /* RID_PTRVALUE */	0,
+
+  /* function names */
+  /* RID_FUNCTION_NAME */      		0,
+  /* RID_PRETTY_FUNCTION_NAME */	0,
+  /* RID_C99_FUNCTION_NAME */		0,
 
   /* C++ */
   /* RID_BOOL */	TYPESPEC,
===================================================================
Index: cp/optimize.c
--- cp/optimize.c	2001/02/22 14:22:02	1.58
+++ cp/optimize.c	2001/03/21 03:52:43
@@ -1075,7 +1075,6 @@ maybe_clone_body (fn)
       VARRAY_FREE (id.fns);
 
       /* Now, expand this function into RTL, if appropriate.  */
-      function_name_declared_p = 1;
       finish_function (0);
       BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
       expand_body (clone);
===================================================================
Index: cp/pt.c
--- cp/pt.c	2001/03/19 23:49:55	1.526
+++ cp/pt.c	2001/03/21 03:52:45
@@ -9939,10 +9939,6 @@ instantiate_decl (d, defer_ok)
       /* Set up context.  */
       start_function (NULL_TREE, d, NULL_TREE, SF_PRE_PARSED);
 
-      /* We already set up __FUNCTION__, etc., so we don't want to do
-	 it again now.  */
-      function_name_declared_p = 1;
-
       /* Substitute into the body of the function.  */
       tsubst_expr (DECL_SAVED_TREE (code_pattern), args,
 		   /*complain=*/1, tmpl);
===================================================================
Index: cp/semantics.c
--- cp/semantics.c	2001/03/19 23:49:56	1.193
+++ cp/semantics.c	2001/03/21 03:52:45
@@ -840,16 +840,6 @@ begin_compound_stmt (has_no_scope)
        to accidentally keep a block *inside* the scopeless block.  */ 
     keep_next_level (0);
 
-  /* If this is the outermost block of the function, declare the
-     variables __FUNCTION__, __PRETTY_FUNCTION__, and so forth.  */
-  if (cfun
-      && !function_name_declared_p
-      && !has_no_scope)
-    {
-      function_name_declared_p = 1;
-      declare_function_name ();
-    }
-
   return r;
 }
 
@@ -1168,7 +1158,6 @@ setup_vtbl_ptr (member_init_list, base_i
     {
       tree if_stmt;
       tree compound_stmt;
-      int saved_cfnd;
 
       /* If the dtor is empty, and we know there is not any possible
 	 way we could use any vtable entries, before they are possibly
@@ -1189,12 +1178,7 @@ setup_vtbl_ptr (member_init_list, base_i
       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 = function_name_declared_p;
-      function_name_declared_p = 1;
       compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
-      function_name_declared_p = saved_cfnd;
 
       /* Make all virtual function table pointers in non-virtual base
 	 classes point to CURRENT_CLASS_TYPE's virtual function
@@ -2424,11 +2408,6 @@ expand_body (fn)
 
   genrtl_start_function (fn);
   current_function_is_thunk = DECL_THUNK_P (fn);
-
-  /* We don't need to redeclare __FUNCTION__, __PRETTY_FUNCTION__, or
-     any of the other magic variables we set up when starting a
-     function body.  */
-  function_name_declared_p = 1;
 
   /* Expand the body.  */
   expand_stmt (DECL_SAVED_TREE (fn));
===================================================================
Index: cp/spew.c
--- cp/spew.c	2001/03/07 01:32:01	1.45
+++ cp/spew.c	2001/03/21 03:52:45
@@ -221,6 +221,12 @@ read_process_identifier (pyylval)
 	case RID_XOR_EQ: pyylval->code = BIT_XOR_EXPR;	return ASSIGN;
 	case RID_NOT_EQ: pyylval->code = NE_EXPR;	return EQCOMPARE;
 
+	case RID_FUNCTION_NAME:
+	case RID_PRETTY_FUNCTION_NAME:
+	case RID_C99_FUNCTION_NAME:
+	  pyylval->ttype = cfun_name_as_string (C_RID_CODE (id));
+	  return STRING;
+
 	default:
 	  if (C_RID_YYCODE (id) == TYPESPEC)
 	    GNU_xref_ref (current_function_decl, IDENTIFIER_POINTER (id));
/bin/bash: cd: /home/zack/src/vanilla.gcc/gcc: No such file or directory
cvs diff: No CVSROOT specified!  Please use the `-d' option
cvs [diff aborted]: or set the CVSROOT environment variable.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]