OSDN Git Service

* alias.c (find_base_value): When copying arguments, return the
[pf3gnuchains/gcc-fork.git] / gcc / dwarfout.c
index 1d29394..cdeed4a 100644 (file)
@@ -1,5 +1,5 @@
 /* Output Dwarf format symbol table information from the GNU C compiler.
-   Copyright (C) 1992, 1993, 1995, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
    Contributed by Ron Guilmette (rfg@monkeys.com) of Network Computing Devices.
 
 This file is part of GNU CC.
@@ -319,7 +319,9 @@ static void output_unsigned_leb128  PROTO((unsigned long));
 static void output_signed_leb128       PROTO((long));
 static inline int is_body_block                PROTO((tree));
 static int fundamental_type_code       PROTO((tree));
+static tree root_type_1                        PROTO((tree, int));
 static tree root_type                  PROTO((tree));
+static void write_modifier_bytes_1     PROTO((tree, int, int, int));
 static void write_modifier_bytes       PROTO((tree, int, int));
 static inline int type_is_fundamental  PROTO((tree));
 static void equate_decl_number_to_die_number PROTO((tree));
@@ -529,153 +531,153 @@ static void generate_macinfo_entry      PROTO((char *, char *));
 */
 
 #ifndef TEXT_BEGIN_LABEL
-#define TEXT_BEGIN_LABEL       ".L_text_b"
+#define TEXT_BEGIN_LABEL       "*.L_text_b"
 #endif
 #ifndef TEXT_END_LABEL
-#define TEXT_END_LABEL         ".L_text_e"
+#define TEXT_END_LABEL         "*.L_text_e"
 #endif
 
 #ifndef DATA_BEGIN_LABEL
-#define DATA_BEGIN_LABEL       ".L_data_b"
+#define DATA_BEGIN_LABEL       "*.L_data_b"
 #endif
 #ifndef DATA_END_LABEL
-#define DATA_END_LABEL         ".L_data_e"
+#define DATA_END_LABEL         "*.L_data_e"
 #endif
 
 #ifndef DATA1_BEGIN_LABEL
-#define DATA1_BEGIN_LABEL      ".L_data1_b"
+#define DATA1_BEGIN_LABEL      "*.L_data1_b"
 #endif
 #ifndef DATA1_END_LABEL
-#define DATA1_END_LABEL                ".L_data1_e"
+#define DATA1_END_LABEL                "*.L_data1_e"
 #endif
 
 #ifndef RODATA_BEGIN_LABEL
-#define RODATA_BEGIN_LABEL     ".L_rodata_b"
+#define RODATA_BEGIN_LABEL     "*.L_rodata_b"
 #endif
 #ifndef RODATA_END_LABEL
-#define RODATA_END_LABEL       ".L_rodata_e"
+#define RODATA_END_LABEL       "*.L_rodata_e"
 #endif
 
 #ifndef RODATA1_BEGIN_LABEL
-#define RODATA1_BEGIN_LABEL    ".L_rodata1_b"
+#define RODATA1_BEGIN_LABEL    "*.L_rodata1_b"
 #endif
 #ifndef RODATA1_END_LABEL
-#define RODATA1_END_LABEL      ".L_rodata1_e"
+#define RODATA1_END_LABEL      "*.L_rodata1_e"
 #endif
 
 #ifndef BSS_BEGIN_LABEL
-#define BSS_BEGIN_LABEL                ".L_bss_b"
+#define BSS_BEGIN_LABEL                "*.L_bss_b"
 #endif
 #ifndef BSS_END_LABEL
-#define BSS_END_LABEL          ".L_bss_e"
+#define BSS_END_LABEL          "*.L_bss_e"
 #endif
 
 #ifndef LINE_BEGIN_LABEL
-#define LINE_BEGIN_LABEL       ".L_line_b"
+#define LINE_BEGIN_LABEL       "*.L_line_b"
 #endif
 #ifndef LINE_LAST_ENTRY_LABEL
-#define LINE_LAST_ENTRY_LABEL  ".L_line_last"
+#define LINE_LAST_ENTRY_LABEL  "*.L_line_last"
 #endif
 #ifndef LINE_END_LABEL
-#define LINE_END_LABEL         ".L_line_e"
+#define LINE_END_LABEL         "*.L_line_e"
 #endif
 
 #ifndef DEBUG_BEGIN_LABEL
-#define DEBUG_BEGIN_LABEL      ".L_debug_b"
+#define DEBUG_BEGIN_LABEL      "*.L_debug_b"
 #endif
 #ifndef SFNAMES_BEGIN_LABEL
-#define SFNAMES_BEGIN_LABEL    ".L_sfnames_b"
+#define SFNAMES_BEGIN_LABEL    "*.L_sfnames_b"
 #endif
 #ifndef SRCINFO_BEGIN_LABEL
-#define SRCINFO_BEGIN_LABEL    ".L_srcinfo_b"
+#define SRCINFO_BEGIN_LABEL    "*.L_srcinfo_b"
 #endif
 #ifndef MACINFO_BEGIN_LABEL
-#define MACINFO_BEGIN_LABEL    ".L_macinfo_b"
+#define MACINFO_BEGIN_LABEL    "*.L_macinfo_b"
 #endif
 
 #ifndef DIE_BEGIN_LABEL_FMT
-#define DIE_BEGIN_LABEL_FMT    ".L_D%u"
+#define DIE_BEGIN_LABEL_FMT    "*.L_D%u"
 #endif
 #ifndef DIE_END_LABEL_FMT
-#define DIE_END_LABEL_FMT      ".L_D%u_e"
+#define DIE_END_LABEL_FMT      "*.L_D%u_e"
 #endif
 #ifndef PUB_DIE_LABEL_FMT
-#define PUB_DIE_LABEL_FMT      ".L_P%u"
+#define PUB_DIE_LABEL_FMT      "*.L_P%u"
 #endif
 #ifndef INSN_LABEL_FMT
-#define INSN_LABEL_FMT         ".L_I%u_%u"
+#define INSN_LABEL_FMT         "*.L_I%u_%u"
 #endif
 #ifndef BLOCK_BEGIN_LABEL_FMT
-#define BLOCK_BEGIN_LABEL_FMT  ".L_B%u"
+#define BLOCK_BEGIN_LABEL_FMT  "*.L_B%u"
 #endif
 #ifndef BLOCK_END_LABEL_FMT
-#define BLOCK_END_LABEL_FMT    ".L_B%u_e"
+#define BLOCK_END_LABEL_FMT    "*.L_B%u_e"
 #endif
 #ifndef SS_BEGIN_LABEL_FMT
-#define SS_BEGIN_LABEL_FMT     ".L_s%u"
+#define SS_BEGIN_LABEL_FMT     "*.L_s%u"
 #endif
 #ifndef SS_END_LABEL_FMT
-#define SS_END_LABEL_FMT       ".L_s%u_e"
+#define SS_END_LABEL_FMT       "*.L_s%u_e"
 #endif
 #ifndef EE_BEGIN_LABEL_FMT
-#define EE_BEGIN_LABEL_FMT     ".L_e%u"
+#define EE_BEGIN_LABEL_FMT     "*.L_e%u"
 #endif
 #ifndef EE_END_LABEL_FMT
-#define EE_END_LABEL_FMT       ".L_e%u_e"
+#define EE_END_LABEL_FMT       "*.L_e%u_e"
 #endif
 #ifndef MT_BEGIN_LABEL_FMT
-#define MT_BEGIN_LABEL_FMT     ".L_t%u"
+#define MT_BEGIN_LABEL_FMT     "*.L_t%u"
 #endif
 #ifndef MT_END_LABEL_FMT
-#define MT_END_LABEL_FMT       ".L_t%u_e"
+#define MT_END_LABEL_FMT       "*.L_t%u_e"
 #endif
 #ifndef LOC_BEGIN_LABEL_FMT
-#define LOC_BEGIN_LABEL_FMT    ".L_l%u"
+#define LOC_BEGIN_LABEL_FMT    "*.L_l%u"
 #endif
 #ifndef LOC_END_LABEL_FMT
-#define LOC_END_LABEL_FMT      ".L_l%u_e"
+#define LOC_END_LABEL_FMT      "*.L_l%u_e"
 #endif
 #ifndef BOUND_BEGIN_LABEL_FMT
-#define BOUND_BEGIN_LABEL_FMT  ".L_b%u_%u_%c"
+#define BOUND_BEGIN_LABEL_FMT  "*.L_b%u_%u_%c"
 #endif
 #ifndef BOUND_END_LABEL_FMT
-#define BOUND_END_LABEL_FMT    ".L_b%u_%u_%c_e"
+#define BOUND_END_LABEL_FMT    "*.L_b%u_%u_%c_e"
 #endif
 #ifndef DERIV_BEGIN_LABEL_FMT
-#define DERIV_BEGIN_LABEL_FMT  ".L_d%u"
+#define DERIV_BEGIN_LABEL_FMT  "*.L_d%u"
 #endif
 #ifndef DERIV_END_LABEL_FMT
-#define DERIV_END_LABEL_FMT    ".L_d%u_e"
+#define DERIV_END_LABEL_FMT    "*.L_d%u_e"
 #endif
 #ifndef SL_BEGIN_LABEL_FMT
-#define SL_BEGIN_LABEL_FMT     ".L_sl%u"
+#define SL_BEGIN_LABEL_FMT     "*.L_sl%u"
 #endif
 #ifndef SL_END_LABEL_FMT
-#define SL_END_LABEL_FMT       ".L_sl%u_e"
+#define SL_END_LABEL_FMT       "*.L_sl%u_e"
 #endif
 #ifndef BODY_BEGIN_LABEL_FMT
-#define BODY_BEGIN_LABEL_FMT   ".L_b%u"
+#define BODY_BEGIN_LABEL_FMT   "*.L_b%u"
 #endif
 #ifndef BODY_END_LABEL_FMT
-#define BODY_END_LABEL_FMT     ".L_b%u_e"
+#define BODY_END_LABEL_FMT     "*.L_b%u_e"
 #endif
 #ifndef FUNC_END_LABEL_FMT
-#define FUNC_END_LABEL_FMT     ".L_f%u_e"
+#define FUNC_END_LABEL_FMT     "*.L_f%u_e"
 #endif
 #ifndef TYPE_NAME_FMT
-#define TYPE_NAME_FMT          ".L_T%u"
+#define TYPE_NAME_FMT          "*.L_T%u"
 #endif
 #ifndef DECL_NAME_FMT
-#define DECL_NAME_FMT          ".L_E%u"
+#define DECL_NAME_FMT          "*.L_E%u"
 #endif
 #ifndef LINE_CODE_LABEL_FMT
-#define LINE_CODE_LABEL_FMT    ".L_LC%u"
+#define LINE_CODE_LABEL_FMT    "*.L_LC%u"
 #endif
 #ifndef SFNAMES_ENTRY_LABEL_FMT
-#define SFNAMES_ENTRY_LABEL_FMT        ".L_F%u"
+#define SFNAMES_ENTRY_LABEL_FMT        "*.L_F%u"
 #endif
 #ifndef LINE_ENTRY_LABEL_FMT
-#define LINE_ENTRY_LABEL_FMT   ".L_LE%u"
+#define LINE_ENTRY_LABEL_FMT   "*.L_LE%u"
 #endif
 \f
 /* Definitions of defaults for various types of primitive assembly language
@@ -694,14 +696,6 @@ static void generate_macinfo_entry PROTO((char *, char *));
   fprintf ((FILE), "\t%s\n", POPSECTION_ASM_OP)
 #endif
 
-#ifndef ASM_OUTPUT_SOURCE_FILENAME
-#define ASM_OUTPUT_SOURCE_FILENAME(FILE,NAME) \
-  do { fprintf (FILE, "\t%s\t", FILE_ASM_OP);                          \
-       output_quoted_string (FILE, NAME);                              \
-       fputc ('\n', FILE);                                             \
-  } while (0)
-#endif
-
 #ifndef ASM_OUTPUT_DWARF_DELTA2
 #define ASM_OUTPUT_DWARF_DELTA2(FILE,LABEL1,LABEL2)                    \
  do {  fprintf ((FILE), "\t%s\t", UNALIGNED_SHORT_ASM_OP);             \
@@ -1447,10 +1441,14 @@ fundamental_type_code (type)
    qualifiers.  */
 
 static tree
-root_type (type)
+root_type_1 (type, count)
      register tree type;
+     register int count;
 {
-  if (TREE_CODE (type) == ERROR_MARK)
+  /* Give up after searching 1000 levels, in case this is a recursive
+     pointer type.  Such types are possible in Ada, but it is not possible
+     to represent them in DWARF1 debug info.  */
+  if (count > 1000)
     return error_mark_node;
 
   switch (TREE_CODE (type))
@@ -1460,25 +1458,42 @@ root_type (type)
 
       case POINTER_TYPE:
       case REFERENCE_TYPE:
-       return type_main_variant (root_type (TREE_TYPE (type)));
+       return root_type_1 (TREE_TYPE (type), count+1);
 
       default:
-       return type_main_variant (type);
+       return type;
     }
 }
 
+static tree
+root_type (type)
+     register tree type;
+{
+  type = root_type_1 (type, 0);
+  if (type != error_mark_node)
+    type = type_main_variant (type);
+  return type;
+}
+
 /* Given a pointer to an arbitrary ..._TYPE tree node, write out a sequence
    of zero or more Dwarf "type-modifier" bytes applicable to the type. */
 
 static void
-write_modifier_bytes (type, decl_const, decl_volatile)
+write_modifier_bytes_1 (type, decl_const, decl_volatile, count)
      register tree type;
      register int decl_const;
      register int decl_volatile;
+     register int count;
 {
   if (TREE_CODE (type) == ERROR_MARK)
     return;
 
+  /* Give up after searching 1000 levels, in case this is a recursive
+     pointer type.  Such types are possible in Ada, but it is not possible
+     to represent them in DWARF1 debug info.  */
+  if (count > 1000)
+    return;
+
   if (TYPE_READONLY (type) || decl_const)
     ASM_OUTPUT_DWARF_TYPE_MODIFIER (asm_out_file, MOD_const);
   if (TYPE_VOLATILE (type) || decl_volatile)
@@ -1487,12 +1502,12 @@ write_modifier_bytes (type, decl_const, decl_volatile)
     {
       case POINTER_TYPE:
        ASM_OUTPUT_DWARF_TYPE_MODIFIER (asm_out_file, MOD_pointer_to);
-       write_modifier_bytes (TREE_TYPE (type), 0, 0);
+       write_modifier_bytes_1 (TREE_TYPE (type), 0, 0, count+1);
        return;
 
       case REFERENCE_TYPE:
        ASM_OUTPUT_DWARF_TYPE_MODIFIER (asm_out_file, MOD_reference_to);
-       write_modifier_bytes (TREE_TYPE (type), 0, 0);
+       write_modifier_bytes_1 (TREE_TYPE (type), 0, 0, count+1);
        return;
 
       case ERROR_MARK:
@@ -1500,6 +1515,15 @@ write_modifier_bytes (type, decl_const, decl_volatile)
        return;
     }
 }
+
+static void
+write_modifier_bytes (type, decl_const, decl_volatile)
+     register tree type;
+     register int decl_const;
+     register int decl_volatile;
+{
+  write_modifier_bytes_1 (type, decl_const, decl_volatile, 0);
+}
 \f
 /* Given a pointer to an arbitrary ..._TYPE tree node, return non-zero if the
    given input type is a Dwarf "fundamental" type.  Otherwise return zero.  */
@@ -1828,7 +1852,7 @@ output_bound_representation (bound, dim_num, u_or_l)
 
            if (TREE_CODE (bound) == SAVE_EXPR)
              output_loc_descriptor
-               (eliminate_regs (SAVE_EXPR_RTL (bound), 0, NULL_RTX));
+               (eliminate_regs (SAVE_EXPR_RTL (bound), 0, NULL_RTX, 0));
          }
 
        ASM_OUTPUT_LABEL (asm_out_file, end_label);
@@ -2035,6 +2059,25 @@ field_byte_offset (decl)
   /* Compute the offset of the containing object in bytes.  */
   object_offset_in_bytes = object_offset_in_align_units * type_align_in_bytes;
 
+  /* The above code assumes that the field does not cross an alignment
+     boundary.  This can happen if PCC_BITFIELD_TYPE_MATTERS is not defined,
+     or if the structure is packed.  If this happens, then we get an object
+     which starts after the bitfield, which means that the bit offset is
+     negative.  Gdb fails when given negative bit offsets.  We avoid this
+     by recomputing using the first bit of the bitfield.  This will give
+     us an object which does not completely contain the bitfield, but it
+     will be aligned, and it will contain the first bit of the bitfield.  */
+  if (object_offset_in_bits > bitpos_int)
+    {
+      deepest_bitpos = bitpos_int + 1;
+      object_offset_in_bits
+       = ceiling (deepest_bitpos, type_align_in_bits) - type_size_in_bits;
+      object_offset_in_align_units = (object_offset_in_bits
+                                     / type_align_in_bits);
+      object_offset_in_bytes = (object_offset_in_align_units
+                               * type_align_in_bytes);
+    }
+
   return object_offset_in_bytes;
 }
 
@@ -2098,7 +2141,7 @@ location_attribute (rtl)
 
   if (! is_pseudo_reg (rtl)
       && (GET_CODE (rtl) != MEM || ! is_pseudo_reg (XEXP (rtl, 0))))
-    output_loc_descriptor (eliminate_regs (rtl, 0, NULL_RTX));
+    output_loc_descriptor (rtl);
 
   ASM_OUTPUT_LABEL (asm_out_file, end_label);
 }
@@ -2352,8 +2395,19 @@ location_or_const_value_attribute (decl)
   if (rtl == NULL_RTX)
     return;
 
+  rtl = eliminate_regs (rtl, 0, NULL_RTX, 0);
+#ifdef LEAF_REG_REMAP
+  if (leaf_function)
+    leaf_renumber_regs_insn (rtl);
+#endif
+
   switch (GET_CODE (rtl))
     {
+    case ADDRESSOF:
+      /* The address of a variable that was optimized away; don't emit
+        anything.  */
+      break;
+
     case CONST_INT:
     case CONST_DOUBLE:
     case CONST_STRING:
@@ -2370,6 +2424,15 @@ location_or_const_value_attribute (decl)
       location_attribute (rtl);
       break;
 
+    case CONCAT:
+      /* ??? CONCAT is used for complex variables, which may have the real
+        part stored in one place and the imag part stored somewhere else.
+        DWARF1 has no way to describe a variable that lives in two different
+        places, so we just describe where the first part lives, and hope that
+        the second part is stored after it.  */
+      location_attribute (XEXP (rtl, 0));
+      break;
+
     default:
       abort ();                /* Should never happen.  */
     }
@@ -2993,16 +3056,22 @@ type_attribute (type, decl_const, decl_volatile)
   register enum tree_code code = TREE_CODE (type);
   register int root_type_modified;
 
-  if (TREE_CODE (type) == ERROR_MARK)
+  if (code == ERROR_MARK)
     return;
 
   /* Handle a special case.  For functions whose return type is void,
      we generate *no* type attribute.  (Note that no object may have
      type `void', so this only applies to function return types.  */
 
-  if (TREE_CODE (type) == VOID_TYPE)
+  if (code == VOID_TYPE)
     return;
 
+  /* If this is a subtype, find the underlying type.  Eventually,
+     this should write out the appropriate subtype info.  */
+  while ((code == INTEGER_TYPE || code == REAL_TYPE)
+        && TREE_TYPE (type) != 0)
+    type = TREE_TYPE (type), code = TREE_CODE (type);
+
   root_type_modified = (code == POINTER_TYPE || code == REFERENCE_TYPE
                        || decl_const || decl_volatile
                        || TYPE_READONLY (type) || TYPE_VOLATILE (type));
@@ -3597,6 +3666,8 @@ output_compile_unit_die (arg)
     language_attribute (LANG_ADA83);
   else if (strcmp (language_string, "GNU F77") == 0)
     language_attribute (LANG_FORTRAN77);
+  else if (strcmp (language_string, "GNU Pascal") == 0)
+    language_attribute (LANG_PASCAL83);
   else if (flag_traditional)
     language_attribute (LANG_C);
   else
@@ -4137,6 +4208,9 @@ output_type (type, containing_scope)
 
       case POINTER_TYPE:
       case REFERENCE_TYPE:
+       /* Prevent infinite recursion in cases where this is a recursive
+          type.  Recursive types are possible in Ada.  */
+       TREE_ASM_WRITTEN (type) = 1;
        /* For these types, all that is required is that we output a DIE
           (or a set of DIEs) to represent the "basis" type.  */
        output_type (TREE_TYPE (type), containing_scope);
@@ -4233,7 +4307,10 @@ output_type (type, containing_scope)
           can safely generate correct Dwarf descriptions for these file-
           scope tagged types.  */
 
-       if (TYPE_SIZE (type) == 0 && !finalizing)
+       if (TYPE_SIZE (type) == 0
+           && (TYPE_CONTEXT (type) == NULL
+               || TREE_CODE_CLASS (TREE_CODE (TYPE_CONTEXT (type))) == 't')
+           && !finalizing)
          return;       /* EARLY EXIT!  Avoid setting TREE_ASM_WRITTEN.  */
 
        /* Prevent infinite recursion in cases where the type of some
@@ -5072,7 +5149,7 @@ dwarfout_file_scope_decl (decl, set_finalizing)
         a return type or a formal parameter type of some function.  */
 
       if (debug_info_level <= DINFO_LEVEL_TERSE)
-       if (DECL_NAME (decl) != NULL
+       if (! TYPE_DECL_IS_STUB (decl)
            || ! TYPE_USED_FOR_FUNCTION (TREE_TYPE (decl)))
           return;
 
@@ -5363,13 +5440,13 @@ dwarfout_line (filename, line)
       ASM_OUTPUT_LABEL (asm_out_file, label);
 
       fputc ('\n', asm_out_file);
-      ASM_OUTPUT_PUSH_SECTION (asm_out_file, LINE_SECTION);
 
       if (use_gnu_debug_info_extensions)
        this_file_entry_num = lookup_filename (filename);
       else
        this_file_entry_num = (unsigned) -1;
 
+      ASM_OUTPUT_PUSH_SECTION (asm_out_file, LINE_SECTION);
       if (this_file_entry_num != prev_file_entry_num)
         {
           char line_entry_label[MAX_ARTIFICIAL_LABEL_BYTES];
@@ -5424,7 +5501,10 @@ dwarfout_start_new_source_file (filename)
 
   sprintf (label, SFNAMES_ENTRY_LABEL_FMT, lookup_filename (filename));
   sprintf (type_and_offset, "0x%08x+%s-%s",
-          ((unsigned) MACINFO_start << 24), label, SFNAMES_BEGIN_LABEL);
+          ((unsigned) MACINFO_start << 24),
+          /* Hack: skip leading '*' .  */
+          (*label == '*') + label,
+          (*SFNAMES_BEGIN_LABEL == '*') + SFNAMES_BEGIN_LABEL);
   generate_macinfo_entry (type_and_offset, "");
 }