[multiple changes]
[platform/upstream/gcc.git] / gcc / dbxout.c
index 6205472..a55d102 100644 (file)
@@ -1,5 +1,5 @@
 /* Output dbx-format symbol table information from GNU compiler.
-   Copyright (C) 1987-2013 Free Software Foundation, Inc.
+   Copyright (C) 1987-2015 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -70,8 +70,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
-
+#include "alias.h"
 #include "tree.h"
+#include "fold-const.h"
 #include "varasm.h"
 #include "stor-layout.h"
 #include "rtl.h"
@@ -84,15 +85,21 @@ along with GCC; see the file COPYING3.  If not see
 #include "diagnostic-core.h"
 #include "toplev.h"
 #include "tm_p.h"
-#include "ggc.h"
 #include "debug.h"
 #include "function.h"
 #include "target.h"
 #include "common/common-target.h"
 #include "langhooks.h"
 #include "obstack.h"
+#include "expmed.h"
+#include "dojump.h"
+#include "explow.h"
+#include "calls.h"
+#include "emit-rtl.h"
+#include "stmt.h"
 #include "expr.h"
 #include "cgraph.h"
+#include "stringpool.h"
 
 #ifdef XCOFF_DEBUGGING_INFO
 #include "xcoffout.h"
@@ -325,7 +332,8 @@ static int dbxout_symbol_location (tree, tree, const char *, rtx);
 static void dbxout_symbol_name (tree, const char *, int);
 static void dbxout_common_name (tree, const char *, stab_code_type);
 static const char *dbxout_common_check (tree, int *);
-static void dbxout_global_decl (tree);
+static void dbxout_early_global_decl (tree);
+static void dbxout_late_global_decl (tree);
 static void dbxout_type_decl (tree, int);
 static void dbxout_handle_pch (unsigned);
 static void debug_free_queue (void);
@@ -347,6 +355,7 @@ const struct gcc_debug_hooks dbx_debug_hooks =
   dbxout_init,
   dbxout_finish,
   debug_nothing_void,
+  debug_nothing_void,
   debug_nothing_int_charstar,
   debug_nothing_int_charstar,
   dbxout_start_source_file,
@@ -365,15 +374,17 @@ const struct gcc_debug_hooks dbx_debug_hooks =
   debug_nothing_tree,                   /* begin_function */
 #endif
   debug_nothing_int,                    /* end_function */
+  debug_nothing_tree,                   /* register_main_translation_unit */
   dbxout_function_decl,
-  dbxout_global_decl,                   /* global_decl */
+  dbxout_early_global_decl,             /* early_global_decl */
+  dbxout_late_global_decl,              /* late_global_decl */
   dbxout_type_decl,                     /* type_decl */
   debug_nothing_tree_tree_tree_bool,    /* imported_module_or_decl */
   debug_nothing_tree,                   /* deferred_inline_function */
   debug_nothing_tree,                   /* outlining_inline_function */
-  debug_nothing_rtx,                    /* label */
+  debug_nothing_rtx_code_label,                 /* label */
   dbxout_handle_pch,                    /* handle_pch */
-  debug_nothing_rtx,                    /* var_location */
+  debug_nothing_rtx_insn,               /* var_location */
   debug_nothing_void,                    /* switch_text_section */
   debug_nothing_tree_tree,              /* set_name */
   0,                                     /* start_end_main_source_file */
@@ -387,6 +398,7 @@ const struct gcc_debug_hooks xcoff_debug_hooks =
   dbxout_init,
   dbxout_finish,
   debug_nothing_void,
+  debug_nothing_void,
   debug_nothing_int_charstar,
   debug_nothing_int_charstar,
   dbxout_start_source_file,
@@ -401,15 +413,17 @@ const struct gcc_debug_hooks xcoff_debug_hooks =
   xcoffout_end_epilogue,
   debug_nothing_tree,                   /* begin_function */
   xcoffout_end_function,
+  debug_nothing_tree,                   /* register_main_translation_unit */
   debug_nothing_tree,                   /* function_decl */
-  dbxout_global_decl,                   /* global_decl */
+  dbxout_early_global_decl,             /* early_global_decl */
+  dbxout_late_global_decl,              /* late_global_decl */
   dbxout_type_decl,                     /* type_decl */
   debug_nothing_tree_tree_tree_bool,    /* imported_module_or_decl */
   debug_nothing_tree,                   /* deferred_inline_function */
   debug_nothing_tree,                   /* outlining_inline_function */
-  debug_nothing_rtx,                    /* label */
+  debug_nothing_rtx_code_label,                 /* label */
   dbxout_handle_pch,                    /* handle_pch */
-  debug_nothing_rtx,                    /* var_location */
+  debug_nothing_rtx_insn,               /* var_location */
   debug_nothing_void,                    /* switch_text_section */
   debug_nothing_tree_tree,              /* set_name */
   0,                                     /* start_end_main_source_file */
@@ -692,88 +706,39 @@ stabstr_U (unsigned HOST_WIDE_INT num)
 static void
 stabstr_O (tree cst)
 {
-  unsigned HOST_WIDE_INT high = TREE_INT_CST_HIGH (cst);
-  unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (cst);
-
-  char buf[128];
-  char *p = buf + sizeof buf;
-
-  /* GDB wants constants with no extra leading "1" bits, so
-     we need to remove any sign-extension that might be
-     present.  */
-  {
-    const unsigned int width = TYPE_PRECISION (TREE_TYPE (cst));
-    if (width == HOST_BITS_PER_DOUBLE_INT)
-      ;
-    else if (width > HOST_BITS_PER_WIDE_INT)
-      high &= (((HOST_WIDE_INT) 1 << (width - HOST_BITS_PER_WIDE_INT)) - 1);
-    else if (width == HOST_BITS_PER_WIDE_INT)
-      high = 0;
-    else
-      high = 0, low &= (((HOST_WIDE_INT) 1 << width) - 1);
-  }
+  int prec = TYPE_PRECISION (TREE_TYPE (cst));
+  int res_pres = prec % 3;
+  int i;
+  unsigned int digit;
 
   /* Leading zero for base indicator.  */
   stabstr_C ('0');
 
   /* If the value is zero, the base indicator will serve as the value
      all by itself.  */
-  if (high == 0 && low == 0)
+  if (wi::eq_p (cst, 0))
     return;
 
-  /* If the high half is zero, we need only print the low half normally.  */
-  if (high == 0)
-    NUMBER_FMT_LOOP (p, low, 8);
-  else
+  /* GDB wants constants with no extra leading "1" bits, so
+     we need to remove any sign-extension that might be
+     present.  */
+  if (res_pres == 1)
     {
-      /* When high != 0, we need to print enough zeroes from low to
-        give the digits from high their proper place-values.  Hence
-        NUMBER_FMT_LOOP cannot be used.  */
-      const int n_digits = HOST_BITS_PER_WIDE_INT / 3;
-      int i;
-
-      for (i = 1; i <= n_digits; i++)
-       {
-         unsigned int digit = low % 8;
-         low /= 8;
-         *--p = '0' + digit;
-       }
-
-      /* Octal digits carry exactly three bits of information.  The
-        width of a HOST_WIDE_INT is not normally a multiple of three.
-        Therefore, the next digit printed probably needs to carry
-        information from both low and high.  */
-      if (HOST_BITS_PER_WIDE_INT % 3 != 0)
-       {
-         const int n_leftover_bits = HOST_BITS_PER_WIDE_INT % 3;
-         const int n_bits_from_high = 3 - n_leftover_bits;
-
-         const unsigned HOST_WIDE_INT
-           low_mask = (((unsigned HOST_WIDE_INT)1) << n_leftover_bits) - 1;
-         const unsigned HOST_WIDE_INT
-           high_mask = (((unsigned HOST_WIDE_INT)1) << n_bits_from_high) - 1;
-
-         unsigned int digit;
-
-         /* At this point, only the bottom n_leftover_bits bits of low
-            should be set.  */
-         gcc_assert (!(low & ~low_mask));
-
-         digit = (low | ((high & high_mask) << n_leftover_bits));
-         high >>= n_bits_from_high;
-
-         *--p = '0' + digit;
-       }
-
-      /* Now we can format high in the normal manner.  However, if
-        the only bits of high that were set were handled by the
-        digit split between low and high, high will now be zero, and
-        we don't want to print extra digits in that case.  */
-      if (high)
-       NUMBER_FMT_LOOP (p, high, 8);
+      digit = wi::extract_uhwi (cst, prec - 1, 1);
+      stabstr_C ('0' + digit);
+    }
+  else if (res_pres == 2)
+    {
+      digit = wi::extract_uhwi (cst, prec - 2, 2);
+      stabstr_C ('0' + digit);
     }
 
-  obstack_grow (&stabstr_ob, p, (buf + sizeof buf) - p);
+  prec -= res_pres;
+  for (i = prec - 3; i >= 0; i = i - 3)
+    {
+      digit = wi::extract_uhwi (cst, i, 3);
+      stabstr_C ('0' + digit);
+    }
 }
 
 /* Called whenever it is safe to break a stabs string into multiple
@@ -985,14 +950,13 @@ static unsigned int ATTRIBUTE_UNUSED
 get_lang_number (void)
 {
   const char *language_string = lang_hooks.name;
-
-  if (strcmp (language_string, "GNU C") == 0)
+  if (lang_GNU_C ())
     return N_SO_C;
-  else if (strcmp (language_string, "GNU C++") == 0)
+  else if (lang_GNU_CXX ())
     return N_SO_CC;
   else if (strcmp (language_string, "GNU F77") == 0)
     return N_SO_FORTRAN;
-  else if (strcmp (language_string, "GNU Fortran") == 0)
+  else if (lang_GNU_Fortran ())
     return N_SO_FORTRAN90; /* CHECKME */
   else if (strcmp (language_string, "GNU Pascal") == 0)
     return N_SO_PASCAL;
@@ -1025,7 +989,7 @@ dbxout_init (const char *input_file_name)
   const char *mapped_name;
 
   typevec_len = 100;
-  typevec = ggc_alloc_cleared_vec_typeinfo (typevec_len);
+  typevec = ggc_cleared_vec_alloc<typeinfo> (typevec_len);
 
   /* stabstr_ob contains one string, which will be just fine with
      1-byte alignment.  */
@@ -1366,10 +1330,16 @@ dbxout_function_decl (tree decl)
 
 #endif /* DBX_DEBUGGING_INFO  */
 
+static void
+dbxout_early_global_decl (tree decl ATTRIBUTE_UNUSED)
+{
+  /* NYI for non-dwarf.  */
+}
+
 /* Debug information for a global DECL.  Called from toplev.c after
    compilation proper has finished.  */
 static void
-dbxout_global_decl (tree decl)
+dbxout_late_global_decl (tree decl)
 {
   if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
     {
@@ -1667,7 +1637,7 @@ dbxout_type_methods (tree type)
 
          /* Also ignore abstract methods; those are only interesting to
             the DWARF backends.  */
-         if (DECL_IGNORED_P (fndecl) || DECL_ABSTRACT (fndecl))
+         if (DECL_IGNORED_P (fndecl) || DECL_ABSTRACT_P (fndecl))
            continue;
 
          /* Redundantly output the plain name, since that's what gdb
@@ -2159,12 +2129,12 @@ dbxout_type (tree type, int full)
               another type's definition; instead, output an xref
               and let the definition come when the name is defined.  */
            stabstr_S ((TREE_CODE (type) == RECORD_TYPE) ? "xs" : "xu");
-           if (TYPE_NAME (type) != 0
-               /* The C frontend creates for anonymous variable length
-                  records/unions TYPE_NAME with DECL_NAME NULL.  */
-               && (TREE_CODE (TYPE_NAME (type)) != TYPE_DECL
-                   || DECL_NAME (TYPE_NAME (type))))
-             dbxout_type_name (type);
+           if (TYPE_IDENTIFIER (type))
+             {
+               /* Note that the C frontend creates for anonymous variable
+                  length records/unions TYPE_NAME with DECL_NAME NULL.  */
+               dbxout_type_name (type);
+             }
            else
              {
                stabstr_S ("$$");
@@ -2206,7 +2176,7 @@ dbxout_type (tree type, int full)
                                   access == access_protected_node
                                   ? '1' :'0');
                    if (BINFO_VIRTUAL_P (child)
-                       && (strcmp (lang_hooks.name, "GNU C++") == 0
+                       && (lang_GNU_CXX ()
                            || strcmp (lang_hooks.name, "GNU Objective-C++") == 0))
                      /* For a virtual base, print the (negative)
                         offset within the vtable where we must look
@@ -2301,10 +2271,7 @@ dbxout_type (tree type, int full)
           if (TREE_CODE (value) == CONST_DECL)
             value = DECL_INITIAL (value);
 
-         if (TREE_INT_CST_HIGH (value) == 0)
-           stabstr_D (TREE_INT_CST_LOW (value));
-         else if (TREE_INT_CST_HIGH (value) == -1
-                  && (HOST_WIDE_INT) TREE_INT_CST_LOW (value) < 0)
+         if (cst_and_fits_in_hwi (value))
            stabstr_D (TREE_INT_CST_LOW (value));
          else
            stabstr_O (value);
@@ -2367,7 +2334,22 @@ dbxout_type (tree type, int full)
       dbxout_type (TREE_TYPE (type), 0);
       break;
 
+    case POINTER_BOUNDS_TYPE:
+      /* No debug info for pointer bounds type supported yet.  */
+      break;
+
     default:
+      /* A C++ function with deduced return type can have a TEMPLATE_TYPE_PARM
+        named 'auto' in its type.
+        No debug info for TEMPLATE_TYPE_PARM type supported yet.  */
+      if (lang_GNU_CXX ())
+       {
+         tree name = TYPE_IDENTIFIER (type);
+         if (name == get_identifier ("auto")
+             || name == get_identifier ("decltype(auto)"))
+           break;
+       }
+
       gcc_unreachable ();
     }
 }
@@ -2427,8 +2409,8 @@ dbxout_type_name (tree type)
   stabstr_I (t);
 }
 
-/* Output leading leading struct or class names needed for qualifying
-   type whose scope is limited to a struct or class.  */
+/* Output leading struct or class names needed for qualifying type
+   whose scope is limited to a struct or class.  */
 
 static void
 dbxout_class_name_qualifiers (tree decl)
@@ -2481,7 +2463,7 @@ dbxout_expand_expr (tree expr)
          /* If this is a var that might not be actually output,
             return NULL, otherwise stabs might reference an undefined
             symbol.  */
-         varpool_node *node = varpool_get_node (expr);
+         varpool_node *node = varpool_node::get (expr);
          if (!node || !node->definition)
            return NULL;
        }
@@ -2504,7 +2486,7 @@ dbxout_expand_expr (tree expr)
     case ARRAY_RANGE_REF:
     case BIT_FIELD_REF:
       {
-       enum machine_mode mode;
+       machine_mode mode;
        HOST_WIDE_INT bitsize, bitpos;
        tree offset, tem;
        int volatilep = 0, unsignedp = 0;
@@ -2536,12 +2518,9 @@ dbxout_expand_expr (tree expr)
 /* Helper function for output_used_types.  Queue one entry from the
    used types hash to be output.  */
 
-static int
-output_used_types_helper (void **slot, void *data)
+bool
+output_used_types_helper (tree const &type, vec<tree> *types_p)
 {
-  tree type = (tree) *slot;
-  vec<tree> *types_p = (vec<tree> *) data;
-
   if ((TREE_CODE (type) == RECORD_TYPE
        || TREE_CODE (type) == UNION_TYPE
        || TREE_CODE (type) == QUAL_UNION_TYPE
@@ -2554,7 +2533,7 @@ output_used_types_helper (void **slot, void *data)
           && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
     types_p->quick_push (TYPE_NAME (type));
 
-  return 1;
+  return true;
 }
 
 /* This is a qsort callback which sorts types and declarations into a
@@ -2596,8 +2575,9 @@ output_used_types (void)
       int i;
       tree type;
 
-      types.create (htab_elements (cfun->used_types_hash));
-      htab_traverse (cfun->used_types_hash, output_used_types_helper, &types);
+      types.create (cfun->used_types_hash->elements ());
+      cfun->used_types_hash->traverse<vec<tree> *, output_used_types_helper>
+               (&types);
 
       /* Sort by UID to prevent dependence on hash table ordering.  */
       types.qsort (output_types_sort);
@@ -2800,9 +2780,7 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED)
                   DBX format, and it confuses some tools such as objdump.  */
                && tree_fits_uhwi_p (TYPE_SIZE (type)))
              {
-               tree name = TYPE_NAME (type);
-               if (TREE_CODE (name) == TYPE_DECL)
-                 name = DECL_NAME (name);
+               tree name = TYPE_IDENTIFIER (type);
 
                dbxout_begin_complex_stabs ();
                stabstr_I (name);
@@ -2859,9 +2837,7 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED)
               This is what represents `struct foo' with no typedef.  */
            /* In C++, the name of a type is the corresponding typedef.
               In C, it is an IDENTIFIER_NODE.  */
-           tree name = TYPE_NAME (type);
-           if (TREE_CODE (name) == TYPE_DECL)
-             name = DECL_NAME (name);
+           tree name = TYPE_IDENTIFIER (type);
 
            dbxout_begin_complex_stabs ();
            stabstr_I (name);
@@ -2945,7 +2921,8 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED)
       if (!decl_rtl)
        DBXOUT_DECR_NESTING_AND_RETURN (0);
 
-      decl_rtl = eliminate_regs (decl_rtl, VOIDmode, NULL_RTX);
+      if (!is_global_var (decl))
+       decl_rtl = eliminate_regs (decl_rtl, VOIDmode, NULL_RTX);
 #ifdef LEAF_REG_REMAP
       if (crtl->uses_only_leaf_regs)
        leaf_renumber_regs_insn (decl_rtl);
@@ -3071,7 +3048,7 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home)
             we rely on the fact that error_mark_node initializers always
             end up in bss for C++ and never end up in bss for C.  */
          if (DECL_INITIAL (decl) == 0
-             || (!strcmp (lang_hooks.name, "GNU C++")
+             || (lang_GNU_CXX ()
                  && DECL_INITIAL (decl) == error_mark_node))
            {
              int offs;