diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9a4cf3f56c5e7a38fc1b67096d5a65692cb0925f..a2016ed738e0151249e809e03ad82e7aa93ed8ca 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,18 @@
-2009-09-10  Jason Merrill  <jason@redhat.com>
+2009-09-13  Eric Botcazou  <ebotcazou@adacore.com>
+
+	* tree.h (DECL_IGNORED_P): Document further effect for FUNCTION_DECL.
+	* dbxout.c (dbxout_function_end): Do not test DECL_IGNORED_P.
+	(dbxout_begin_function): Likewise.
+	* final.c (dwarf2_debug_info_emitted_p): New predicate.
+	(final_start_function): Do not emit debug info if DECL_IGNORED_P is
+	set on the function.
+	(final_end_function): Likewise.
+	(final_scan_insn): Likewise.
+	(rest_of_handle_final): Likewise.
+	* varasm.c (assemble_start_function): Likewise.
+	* config/rs6000/xcoff.h (ASM_DECLARE_FUNCTION_NAME): Likewise.
+
+2009-09-12  Jason Merrill  <jason@redhat.com>
 
 	* dbgcnt.c (dbg_cnt_process_single_pair): constify.
 	* opts.c (common_handle_option): constify.
diff --git a/gcc/config/rs6000/xcoff.h b/gcc/config/rs6000/xcoff.h
index 6560f319a25aaa7e0f4bc1d3698507672a885a3b..e5c47822355df140d1e92c777137c15ea8ba5788 100644
--- a/gcc/config/rs6000/xcoff.h
+++ b/gcc/config/rs6000/xcoff.h
@@ -190,7 +190,7 @@
   putc ('.', FILE);						\
   RS6000_OUTPUT_BASENAME (FILE, buffer);			\
   fputs (":\n", FILE);						\
-  if (write_symbols != NO_DEBUG)				\
+  if (write_symbols != NO_DEBUG && !DECL_IGNORED_P (DECL))	\
     xcoffout_declare_function (FILE, DECL, buffer);		\
 }
 
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index bc7965e25b8f1dc26f51094d81513d77a65b13a9..097b20be860e48cabbcba858163dfd7c67d28d24 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -902,7 +902,7 @@ dbxout_finish_complex_stabs (tree sym, stab_code_type code,
 #if defined (DBX_DEBUGGING_INFO)
 
 static void
-dbxout_function_end (tree decl)
+dbxout_function_end (tree decl ATTRIBUTE_UNUSED)
 {
   char lscope_label_name[100];
 
@@ -921,8 +921,7 @@ dbxout_function_end (tree decl)
      named sections.  */
   if (!use_gnu_debug_info_extensions
       || NO_DBX_FUNCTION_END
-      || !targetm.have_named_sections
-      || DECL_IGNORED_P (decl))
+      || !targetm.have_named_sections)
     return;
 
   /* By convention, GCC will mark the end of a function with an N_FUN
@@ -3683,9 +3682,6 @@ dbxout_begin_function (tree decl)
 {
   int saved_tree_used1;
 
-  if (DECL_IGNORED_P (decl))
-    return;
-
   saved_tree_used1 = TREE_USED (decl);
   TREE_USED (decl) = 1;
   if (DECL_NAME (DECL_RESULT (decl)) != 0)
diff --git a/gcc/final.c b/gcc/final.c
index d8ecc5177f041d944095697dcdc06a6d2c322031..3ecb415d79525f1649877396bc84a709d8b8cada 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -1484,6 +1484,20 @@ remap_debug_filename (const char *filename)
   return ggc_strdup (s);
 }
 
+/* Return true if DWARF2 debug info can be emitted for DECL.  */
+
+static bool
+dwarf2_debug_info_emitted_p (tree decl)
+{
+  if (write_symbols != DWARF2_DEBUG && write_symbols != VMS_AND_DWARF2_DEBUG)
+    return false;
+
+  if (DECL_IGNORED_P (decl))
+    return false;
+
+  return true;
+}
+
 /* Output assembler code for the start of a function,
    and initialize some of the variables in this file
    for the new function.  The label for the function and associated
@@ -1508,10 +1522,11 @@ final_start_function (rtx first ATTRIBUTE_UNUSED, FILE *file,
 
   high_block_linenum = high_function_linenum = last_linenum;
 
-  (*debug_hooks->begin_prologue) (last_linenum, last_filename);
+  if (!DECL_IGNORED_P (current_function_decl))
+    debug_hooks->begin_prologue (last_linenum, last_filename);
 
 #if defined (DWARF2_UNWIND_INFO) || defined (TARGET_UNWIND_INFO)
-  if (write_symbols != DWARF2_DEBUG && write_symbols != VMS_AND_DWARF2_DEBUG)
+  if (!dwarf2_debug_info_emitted_p (current_function_decl))
     dwarf2out_begin_prologue (0, NULL);
 #endif
 
@@ -1648,17 +1663,19 @@ final_end_function (void)
 {
   app_disable ();
 
-  (*debug_hooks->end_function) (high_function_linenum);
+  if (!DECL_IGNORED_P (current_function_decl))
+    debug_hooks->end_function (high_function_linenum);
 
   /* Finally, output the function epilogue:
      code to restore the stack frame and return to the caller.  */
   targetm.asm_out.function_epilogue (asm_out_file, get_frame_size ());
 
   /* And debug output.  */
-  (*debug_hooks->end_epilogue) (last_linenum, last_filename);
+  if (!DECL_IGNORED_P (current_function_decl))
+    debug_hooks->end_epilogue (last_linenum, last_filename);
 
 #if defined (DWARF2_UNWIND_INFO)
-  if (write_symbols != DWARF2_DEBUG && write_symbols != VMS_AND_DWARF2_DEBUG
+  if (!dwarf2_debug_info_emitted_p (current_function_decl)
       && dwarf2out_do_frame ())
     dwarf2out_end_epilogue (last_linenum, last_filename);
 #endif
@@ -1839,7 +1856,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
 	    dwarf2out_switch_text_section ();
 	  else
 #endif
-	    (*debug_hooks->switch_text_section) ();
+	  if (!DECL_IGNORED_P (current_function_decl))
+	    debug_hooks->switch_text_section ();
 
 	  switch_to_section (current_function_section ());
 	  break;
@@ -1905,7 +1923,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
 
 	case NOTE_INSN_FUNCTION_BEG:
 	  app_disable ();
-	  (*debug_hooks->end_prologue) (last_linenum, last_filename);
+	  if (!DECL_IGNORED_P (current_function_decl))
+	    debug_hooks->end_prologue (last_linenum, last_filename);
 
 	  if ((*seen & (SEEN_EMITTED | SEEN_NOTE)) == SEEN_NOTE)
 	    {
@@ -1931,7 +1950,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
 	      high_block_linenum = last_linenum;
 
 	      /* Output debugging info about the symbol-block beginning.  */
-	      (*debug_hooks->begin_block) (last_linenum, n);
+	      if (!DECL_IGNORED_P (current_function_decl))
+		debug_hooks->begin_block (last_linenum, n);
 
 	      /* Mark this block as output.  */
 	      TREE_ASM_WRITTEN (NOTE_BLOCK (insn)) = 1;
@@ -1965,7 +1985,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
 	      --block_depth;
 	      gcc_assert (block_depth >= 0);
 
-	      (*debug_hooks->end_block) (high_block_linenum, n);
+	      if (!DECL_IGNORED_P (current_function_decl))
+		debug_hooks->end_block (high_block_linenum, n);
 	    }
 	  if (write_symbols == DBX_DEBUG
 	      || write_symbols == SDB_DEBUG)
@@ -1995,7 +2016,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
 	  break;
 
 	case NOTE_INSN_VAR_LOCATION:
-	  (*debug_hooks->var_location) (insn);
+	  if (!DECL_IGNORED_P (current_function_decl))
+	    debug_hooks->var_location (insn);
 	  break;
 
 	default:
@@ -2038,8 +2060,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
       CC_STATUS_INIT;
 #endif
 
-      if (LABEL_NAME (insn))
-	(*debug_hooks->label) (insn);
+      if (!DECL_IGNORED_P (current_function_decl) && LABEL_NAME (insn))
+	debug_hooks->label (insn);
 
       app_disable ();
 
@@ -2193,13 +2215,10 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
 	  }
 	/* Output this line note if it is the first or the last line
 	   note in a row.  */
-	if (notice_source_line (insn, &is_stmt))
-	  {
-	    (*debug_hooks->source_line) (last_linenum,
-	                                 last_filename,
-	                                 last_discriminator,
-	                                 is_stmt);
-	  }
+	if (!DECL_IGNORED_P (current_function_decl)
+	    && notice_source_line (insn, &is_stmt))
+	  (*debug_hooks->source_line) (last_linenum, last_filename,
+				       last_discriminator, is_stmt);
 
 	if (GET_CODE (body) == ASM_INPUT)
 	  {
@@ -4261,7 +4280,8 @@ rest_of_handle_final (void)
      *will* be routed past here.  */
 
   timevar_push (TV_SYMOUT);
-  (*debug_hooks->function_decl) (current_function_decl);
+  if (!DECL_IGNORED_P (current_function_decl))
+    debug_hooks->function_decl (current_function_decl);
   timevar_pop (TV_SYMOUT);
 
   /* Release the blocks that are linked to DECL_INITIAL() to free the memory.  */
diff --git a/gcc/tree.h b/gcc/tree.h
index 7b431af6199d9754a54c101844a3ae7176d9c7d9..45391d3fb9493a11b69b02a9db1a7a7372bc1175 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2539,7 +2539,8 @@ struct GTY(()) tree_decl_minimal {
   (DECL_COMMON_CHECK (NODE)->decl_common.debug_expr_is_from)
 
 /* Nonzero for a given ..._DECL node means that the name of this node should
-   be ignored for symbolic debug purposes.  */
+   be ignored for symbolic debug purposes.  Moreover, for a FUNCTION_DECL,
+   the body of the function should also be ignored.  */
 #define DECL_IGNORED_P(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.ignored_flag)
 
 /* Nonzero for a given ..._DECL node means that this node represents an
diff --git a/gcc/varasm.c b/gcc/varasm.c
index a7fa83fc1074601d45d85188f17291bfbd45aaa7..f8cc2914693b57365ffcf00d745f26203b5626bb 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -1749,7 +1749,8 @@ assemble_start_function (tree decl, const char *fnname)
   ASM_OUTPUT_FUNCTION_PREFIX (asm_out_file, fnname);
 #endif
 
-  (*debug_hooks->begin_function) (decl);
+  if (!DECL_IGNORED_P (decl))
+    (*debug_hooks->begin_function) (decl);
 
   /* Make function name accessible from other files, if appropriate.  */