OSDN Git Service

Backport the fix for PR tree-optimization/49536 from mainline.
[pf3gnuchains/gcc-fork.git] / gcc / xcoffout.c
index 36a1e72..84b1436 100644 (file)
@@ -1,12 +1,12 @@
 /* Output xcoff-format symbol table information from GNU compiler.
-   Copyright (C) 1992, 1994, 1995, 1997, 1998, 1999, 2000
-   Free Software Foundation, Inc.
+   Copyright (C) 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2002, 2003, 2004,
+   2007, 2008, 2010  Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -15,9 +15,8 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 /* Output xcoff-format symbol table data.  The main functionality is contained
    in dbxout.c.  This file implements the sdbout-like parts of the xcoff
@@ -26,17 +25,21 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 #include "config.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 #include "tree.h"
 #include "rtl.h"
 #include "flags.h"
-#include "toplev.h"
+#include "diagnostic-core.h"
 #include "output.h"
 #include "ggc.h"
+#include "target.h"
+#include "debug.h"
 
 #ifdef XCOFF_DEBUGGING_INFO
 
 /* This defines the C_* storage classes.  */
-#include "dbxstclass.h"
+#include "xcoff.h"
 #include "xcoffout.h"
 #include "dbxout.h"
 #include "gstab.h"
@@ -74,12 +77,21 @@ const char *xcoff_lastfile;
 #define ABS_OR_RELATIVE_LINENO(LINENO)         \
 ((xcoff_inlining) ? (LINENO) : (LINENO) - xcoff_begin_function_line)
 
-/* Output source line numbers via ".line" rather than ".stabd".  */
-#define ASM_OUTPUT_SOURCE_LINE(FILE,LINENUM) \
-  do {                                         \
-    if (xcoff_begin_function_line >= 0)                \
-      fprintf (FILE, "\t.line\t%d\n", ABS_OR_RELATIVE_LINENO (LINENUM)); \
-  } while (0)
+/* Output source line numbers via ".line".  */
+#define ASM_OUTPUT_LINE(FILE,LINENUM)                                     \
+  do                                                                      \
+    {                                                                     \
+      /* Make sure we're in a function and prevent output of .line 0, as   \
+        line # 0 is meant for symbol addresses in xcoff.  Additionally,   \
+        line numbers are 'unsigned short' in 32-bit mode.  */             \
+      if (xcoff_begin_function_line >= 0)                                 \
+       {                                                                  \
+         int lno = ABS_OR_RELATIVE_LINENO (LINENUM);                      \
+         if (lno > 0 && (TARGET_64BIT || lno <= (int)USHRT_MAX))          \
+           fprintf (FILE, "\t.line\t%d\n", lno);                          \
+       }                                                                  \
+    }                                                                     \
+  while (0)
 
 #define ASM_OUTPUT_LFB(FILE,LINENUM) \
 {                                              \
@@ -93,11 +105,13 @@ const char *xcoff_lastfile;
        ? xcoff_current_include_file : main_input_filename); \
 }
 
-#define ASM_OUTPUT_LFE(FILE,LINENUM) \
-  do {                                         \
-    fprintf (FILE, "\t.ef\t%d\n", (LINENUM));  \
-    xcoff_begin_function_line = -1;            \
-  } while (0)
+#define ASM_OUTPUT_LFE(FILE,LINENUM)           \
+  do                                           \
+    {                                          \
+      fprintf (FILE, "\t.ef\t%d\n", (LINENUM));        \
+      xcoff_begin_function_line = -1;          \
+    }                                          \
+  while (0)
 
 #define ASM_OUTPUT_LBB(FILE,LINENUM,BLOCKNUM) \
   fprintf (FILE, "\t.bb\t%d\n", ABS_OR_RELATIVE_LINENO (LINENUM))
@@ -105,75 +119,84 @@ const char *xcoff_lastfile;
 #define ASM_OUTPUT_LBE(FILE,LINENUM,BLOCKNUM) \
   fprintf (FILE, "\t.eb\t%d\n", ABS_OR_RELATIVE_LINENO (LINENUM))
 
-static void assign_type_number         PARAMS ((tree, const char *, int));
-static void xcoffout_block             PARAMS ((tree, int, tree));
-static void xcoffout_source_file       PARAMS ((FILE *, const char *, int));
+static void xcoffout_block (tree, int, tree);
+static void xcoffout_source_file (FILE *, const char *, int);
 \f
 /* Support routines for XCOFF debugging info.  */
 
-/* Assign NUMBER as the stabx type number for the type described by NAME.
-   Search all decls in the list SYMS to find the type NAME.  */
-
-static void
-assign_type_number (syms, name, number)
-     tree syms;
-     const char *name;
-     int number;
-{
-  tree decl;
-
-  for (decl = syms; decl; decl = TREE_CHAIN (decl))
-    if (DECL_NAME (decl)
-       && strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), name) == 0)
-      {
-       TREE_ASM_WRITTEN (decl) = 1;
-       TYPE_SYMTAB_ADDRESS (TREE_TYPE (decl)) = number;
-      }
-}
-
-/* Setup gcc primitive types to use the XCOFF built-in type numbers where
-   possible.  */
-
-void
-xcoff_output_standard_types (syms)
-     tree syms;
+struct xcoff_type_number
 {
-  /* Handle built-in C types here.  */
-
-  assign_type_number (syms, "int", -1);
-  assign_type_number (syms, "char", -2);
-  assign_type_number (syms, "short int", -3);
-  assign_type_number (syms, "long int", (TARGET_64BIT ? -31 : -4));
-  assign_type_number (syms, "unsigned char", -5);
-  assign_type_number (syms, "signed char", -6);
-  assign_type_number (syms, "short unsigned int", -7);
-  assign_type_number (syms, "unsigned int", -8);
+  const char *name;
+  int number;
+};
+static const struct xcoff_type_number xcoff_type_numbers[] = {
+  { "int", -1 },
+  { "char", -2 },
+  { "short int", -3 },
+  { "long int", -4 },  /* fiddled to -31 if 64 bits */
+  { "unsigned char", -5 },
+  { "signed char", -6 },
+  { "short unsigned int", -7 },
+  { "unsigned int", -8 },
   /* No such type "unsigned".  */
-  assign_type_number (syms, "long unsigned int", (TARGET_64BIT ? -32 : -10));
-  assign_type_number (syms, "void", -11);
-  assign_type_number (syms, "float", -12);
-  assign_type_number (syms, "double", -13);
-  assign_type_number (syms, "long double", -14);
+  { "long unsigned int", -10 }, /* fiddled to -32 if 64 bits */
+  { "void", -11 },
+  { "float", -12 },
+  { "double", -13 },
+  { "long double", -14 },
   /* Pascal and Fortran types run from -15 to -29.  */
-  assign_type_number (syms, "wchar", -30);
-  assign_type_number (syms, "long long int", -31);
-  assign_type_number (syms, "long long unsigned int", -32);
+  { "wchar", -30 },  /* XXX Should be "wchar_t" ? */
+  { "long long int", -31 },
+  { "long long unsigned int", -32 },
   /* Additional Fortran types run from -33 to -37.  */
 
   /* ??? Should also handle built-in C++ and Obj-C types.  There perhaps
      aren't any that C doesn't already have.  */
+};
+
+/* Returns an XCOFF fundamental type number for DECL (assumed to be a
+   TYPE_DECL), or 0 if dbxout.c should assign a type number normally.  */
+int
+xcoff_assign_fundamental_type_number (tree decl)
+{
+  const char *name;
+  size_t i;
+
+  /* Do not waste time searching the list for non-intrinsic types.  */
+  if (DECL_NAME (decl) == 0 || ! DECL_IS_BUILTIN (decl))
+    return 0;
+
+  name = IDENTIFIER_POINTER (DECL_NAME (decl));
+
+  /* Linear search, blech, but the list is too small to bother
+     doing anything else.  */
+  for (i = 0; i < ARRAY_SIZE (xcoff_type_numbers); i++)
+    if (!strcmp (xcoff_type_numbers[i].name, name))
+      goto found;
+  return 0;
+
+ found:
+  /* -4 and -10 should be replaced with -31 and -32, respectively,
+     when used for a 64-bit type.  */
+  if (int_size_in_bytes (TREE_TYPE (decl)) == 8)
+    {
+      if (xcoff_type_numbers[i].number == -4)
+       return -31;
+      if (xcoff_type_numbers[i].number == -10)
+       return -32;
+    }
+  return xcoff_type_numbers[i].number;
 }
 
 /* Print an error message for unrecognized stab codes.  */
 
 #define UNKNOWN_STAB(STR)      \
-  internal_error ("No sclass for %s stab (0x%x)\n", STR, stab)
+  internal_error ("no sclass for %s stab (0x%x)", STR, stab)
 
 /* Conversion routine from BSD stabs to AIX storage classes.  */
 
 int
-stab_to_sclass (stab)
-     int stab;
+stab_to_sclass (int stab)
 {
   switch (stab)
     {
@@ -275,10 +298,7 @@ stab_to_sclass (stab)
    INLINE_P is true if this is from an inlined function.  */
 
 static void
-xcoffout_source_file (file, filename, inline_p)
-     FILE *file;
-     const char *filename;
-     int inline_p;
+xcoffout_source_file (FILE *file, const char *filename, int inline_p)
 {
   if (filename
       && (xcoff_lastfile == 0 || strcmp (filename, xcoff_lastfile)
@@ -288,7 +308,8 @@ xcoffout_source_file (file, filename, inline_p)
       if (xcoff_current_include_file)
        {
          fprintf (file, "\t.ei\t");
-         output_quoted_string (file, xcoff_current_include_file);
+         output_quoted_string (file,
+             remap_debug_filename (xcoff_current_include_file));
          fprintf (file, "\n");
          xcoff_current_include_file = NULL;
        }
@@ -296,7 +317,7 @@ xcoffout_source_file (file, filename, inline_p)
       if (strcmp (main_input_filename, filename) || inline_p)
        {
          fprintf (file, "\t.bi\t");
-         output_quoted_string (file, filename);
+         output_quoted_string (file, remap_debug_filename (filename));
          fprintf (file, "\n");
          xcoff_current_include_file = filename;
        }
@@ -307,16 +328,16 @@ xcoffout_source_file (file, filename, inline_p)
 /* Output a line number symbol entry for location (FILENAME, LINE).  */
 
 void
-xcoffout_source_line (line, filename)
-     unsigned int line;
-     const char *filename;
+xcoffout_source_line (unsigned int line, const char *filename,
+                      int discriminator ATTRIBUTE_UNUSED,
+                      bool is_stmt ATTRIBUTE_UNUSED)
 {
   bool inline_p = (strcmp (xcoff_current_function_file, filename) != 0
                   || (int) line < xcoff_begin_function_line);
 
   xcoffout_source_file (asm_out_file, filename, inline_p);
 
-  ASM_OUTPUT_SOURCE_LINE (asm_out_file, line);
+  ASM_OUTPUT_LINE (asm_out_file, line);
 }
 \f
 /* Output the symbols defined in block number DO_BLOCK.
@@ -327,10 +348,7 @@ xcoffout_source_line (line, filename)
 static int do_block = 0;
 
 static void
-xcoffout_block (block, depth, args)
-     tree block;
-     int depth;
-     tree args;
+xcoffout_block (tree block, int depth, tree args)
 {
   while (block)
     {
@@ -369,9 +387,7 @@ xcoffout_block (block, depth, args)
    if the count starts at 0 for the outermost one.  */
 
 void
-xcoffout_begin_block (line, n)
-     unsigned int line;
-     unsigned int n;
+xcoffout_begin_block (unsigned int line, unsigned int n)
 {
   tree decl = current_function_decl;
 
@@ -387,9 +403,7 @@ xcoffout_begin_block (line, n)
 /* Describe the end line-number of an internal block within a function.  */
 
 void
-xcoffout_end_block (line, n)
-     unsigned int line;
-     unsigned int n;
+xcoffout_end_block (unsigned int line, unsigned int n)
 {
   if (n != 1)
     ASM_OUTPUT_LBE (asm_out_file, line, n);
@@ -399,27 +413,20 @@ xcoffout_end_block (line, n)
    Declare function as needed for debugging.  */
 
 void
-xcoffout_declare_function (file, decl, name)
-     FILE *file;
-     tree decl;
-     const char *name;
+xcoffout_declare_function (FILE *file, tree decl, const char *name)
 {
-  int i;
+  size_t len;
 
   if (*name == '*')
     name++;
-  else
-    for (i = 0; name[i]; ++i)
-      {
-       if (name[i] == '[')
-         {
-           char *n = (char *) alloca (i + 1);
-           strncpy (n, name, i);
-           n[i] = '\0';
-           name = n;
-           break;
-         }
-      }
+  len = strlen (name);
+  if (name[len - 1] == ']')
+    {
+      char *n = XALLOCAVEC (char, len - 3);
+      memcpy (n, name, len - 4);
+      n[len - 4] = '\0';
+      name = n;
+    }
 
   /* Any pending .bi or .ei must occur before the .function pseudo op.
      Otherwise debuggers will think that the function is in the previous
@@ -439,9 +446,8 @@ xcoffout_declare_function (file, decl, name)
    Record the file name that this function is contained in.  */
 
 void
-xcoffout_begin_prologue (line, file)
-     unsigned int line;
-     const char *file ATTRIBUTE_UNUSED;
+xcoffout_begin_prologue (unsigned int line,
+                        const char *file ATTRIBUTE_UNUSED)
 {
   ASM_OUTPUT_LFB (asm_out_file, line);
   dbxout_parms (DECL_ARGUMENTS (current_function_decl));
@@ -454,15 +460,14 @@ xcoffout_begin_prologue (line, file)
   xcoffout_block (DECL_INITIAL (current_function_decl), 0,
                  DECL_ARGUMENTS (current_function_decl));
 
-  ASM_OUTPUT_SOURCE_LINE (asm_out_file, line);
+  ASM_OUTPUT_LINE (asm_out_file, line);
 }
 
 /* Called at end of function (before epilogue).
    Describe end of outermost block.  */
 
 void
-xcoffout_end_function (last_linenum)
-     unsigned int last_linenum;
+xcoffout_end_function (unsigned int last_linenum)
 {
   ASM_OUTPUT_LFE (asm_out_file, last_linenum);
 }
@@ -471,7 +476,8 @@ xcoffout_end_function (last_linenum)
    Called after the epilogue is output.  */
 
 void
-xcoffout_end_epilogue ()
+xcoffout_end_epilogue (unsigned int line ATTRIBUTE_UNUSED,
+                      const char *file ATTRIBUTE_UNUSED)
 {
   /* We need to pass the correct function size to .function, otherwise,
      the xas assembler can't figure out the correct size for the function