OSDN Git Service

Fix required by libjava/libltdl import.
[pf3gnuchains/gcc-fork.git] / gcc / dbxout.c
index 4265c9c..dee3839 100644 (file)
@@ -96,7 +96,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #undef DBXOUT_DECR_NESTING
 #define DBXOUT_DECR_NESTING \
   if (--debug_nesting == 0 && symbol_queue_index > 0) \
-    debug_flush_symbol_queue ()
+    { emit_pending_bincls_if_required (); debug_flush_symbol_queue (); }
 
 #undef DBXOUT_DECR_NESTING_AND_RETURN
 #define DBXOUT_DECR_NESTING_AND_RETURN(x) \
@@ -179,20 +179,34 @@ static GTY(()) int typevec_len;
 
 static GTY(()) int next_type_number;
 
+enum binclstatus {BINCL_NOT_REQUIRED, BINCL_PENDING, BINCL_PROCESSED};
+
 /* When using N_BINCL in dbx output, each type number is actually a
    pair of the file number and the type number within the file.
    This is a stack of input files.  */
 
-struct dbx_file GTY(())
+struct dbx_file
 {
   struct dbx_file *next;
   int file_number;
   int next_type_number;
+  enum binclstatus bincl_status;  /* Keep track of lazy bincl.  */
+  const char *pending_bincl_name; /* Name of bincl.  */
+  struct dbx_file *prev;          /* Chain to traverse all pending bincls.  */
 };
 
-/* This is the top of the stack.  */
-
-static GTY(()) struct dbx_file *current_file;
+/* This is the top of the stack.  
+   
+   This is not saved for PCH, because restoring a PCH should not change it.
+   next_file_number does have to be saved, because the PCH may use some
+   file numbers; however, just before restoring a PCH, next_file_number
+   should always be 0 because we should not have needed any file numbers
+   yet.  */
+
+#if (defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)) \
+    && defined (DBX_USE_BINCL)
+static struct dbx_file *current_file;
+#endif
 
 /* This is the next file number to use.  */
 
@@ -231,6 +245,11 @@ static GTY(()) int lastfile_is_base;
 
 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
 
+#ifdef DBX_USE_BINCL
+/* If zero then there is no pending BINCL.  */
+static int pending_bincls = 0;
+#endif
+
 /* The original input file name.  */
 static const char *base_input_file;
 
@@ -307,12 +326,17 @@ static int current_sym_nchars;
 #define CONTIN do { } while (0)
 #endif
 
+#ifdef DBX_USE_BINCL
+static void emit_bincl_stab             (const char *c);
+static void emit_pending_bincls         (void);
+#endif
+static inline void emit_pending_bincls_if_required (void);
+
 static void dbxout_init (const char *);
 static void dbxout_finish (const char *);
 static void dbxout_start_source_file (unsigned, const char *);
 static void dbxout_end_source_file (unsigned);
 static void dbxout_typedefs (tree);
-static void dbxout_fptype_value (tree);
 static void dbxout_type_index (tree);
 #if DBX_CONTIN_LENGTH > 0
 static void dbxout_continue (void);
@@ -443,7 +467,7 @@ dbxout_init (const char *input_file_name)
   asmfile = asm_out_file;
 
   typevec_len = 100;
-  typevec = (struct typeinfo *) ggc_calloc (typevec_len, sizeof typevec[0]);
+  typevec = ggc_calloc (typevec_len, sizeof typevec[0]);
 
   /* Convert Ltext into the appropriate format for local labels in case
      the system doesn't insert underscores in front of user generated
@@ -453,7 +477,8 @@ dbxout_init (const char *input_file_name)
   /* Put the current working directory in an N_SO symbol.  */
   if (use_gnu_debug_info_extensions)
     {
-      if (!cwd && (cwd = getpwd ()) && (!*cwd || cwd[strlen (cwd) - 1] != '/'))
+      if (!cwd && (cwd = get_src_pwd ())
+         && (!*cwd || cwd[strlen (cwd) - 1] != '/'))
        cwd = concat (cwd, FILE_NAME_JOINER, NULL);
       if (cwd)
        {
@@ -497,11 +522,14 @@ dbxout_init (const char *input_file_name)
   next_type_number = 1;
 
 #ifdef DBX_USE_BINCL
-  current_file = (struct dbx_file *) ggc_alloc (sizeof *current_file);
+  current_file = xmalloc (sizeof *current_file);
   current_file->next = NULL;
   current_file->file_number = 0;
   current_file->next_type_number = 1;
   next_file_number = 1;
+  current_file->prev = NULL;
+  current_file->bincl_status = BINCL_NOT_REQUIRED;
+  current_file->pending_bincl_name = NULL;
 #endif
 
   /* Make sure that types `int' and `char' have numbers 1 and 2.
@@ -515,33 +543,90 @@ dbxout_init (const char *input_file_name)
   DBX_OUTPUT_STANDARD_TYPES (syms);
 #endif
 
-  /* Get all permanent types that have typedef names,
-     and output them all, except for those already output.  */
-
+  /* Get all permanent types that have typedef names, and output them
+     all, except for those already output.  Some language front ends
+     put these declarations in the top-level scope; some do not.  */
+  dbxout_typedefs ((*lang_hooks.decls.builtin_type_decls) ());
   dbxout_typedefs (syms);
 }
 
-/* Output any typedef names for types described by TYPE_DECLs in SYMS,
-   in the reverse order from that which is found in SYMS.  */
+/* Output any typedef names for types described by TYPE_DECLs in SYMS.  */
 
 static void
 dbxout_typedefs (tree syms)
 {
-  if (syms)
+  for (; syms != NULL_TREE; syms = TREE_CHAIN (syms))
     {
-      dbxout_typedefs (TREE_CHAIN (syms));
       if (TREE_CODE (syms) == TYPE_DECL)
        {
          tree type = TREE_TYPE (syms);
          if (TYPE_NAME (type)
              && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
-             && COMPLETE_TYPE_P (type)
+             && COMPLETE_OR_VOID_TYPE_P (type)
              && ! TREE_ASM_WRITTEN (TYPE_NAME (type)))
            dbxout_symbol (TYPE_NAME (type), 0);
        }
     }
 }
 
+#ifdef DBX_USE_BINCL
+/* Emit BINCL stab using given name.  */
+static void
+emit_bincl_stab (const char *name)
+{
+  fprintf (asmfile, "%s", ASM_STABS_OP);
+  output_quoted_string (asmfile, name);
+  fprintf (asmfile, ",%d,0,0,0\n", N_BINCL);
+}
+
+/* If there are pending bincls then it is time to emit all of them.  */
+
+static inline void
+emit_pending_bincls_if_required (void)
+{
+  if (pending_bincls)
+    emit_pending_bincls ();
+}
+
+/* Emit all pending bincls.  */
+
+static void
+emit_pending_bincls (void)
+{
+  struct dbx_file *f = current_file;
+
+  /* Find first pending bincl.  */
+  while (f->bincl_status == BINCL_PENDING)
+    f = f->next;
+
+  /* Now emit all bincls.  */
+  f = f->prev;
+
+  while (f)
+    {
+      if (f->bincl_status == BINCL_PENDING)
+        {
+          emit_bincl_stab (f->pending_bincl_name);
+
+         /* Update file number and status.  */
+          f->file_number = next_file_number++;
+          f->bincl_status = BINCL_PROCESSED;
+        }
+      if (f == current_file)
+        break;
+      f = f->prev;
+    }
+
+  /* All pending bincls have been emitted.  */
+  pending_bincls = 0;
+}
+
+#else
+
+static inline void
+emit_pending_bincls_if_required (void) {}
+#endif
+
 /* Change to reading from a new source file.  Generate a N_BINCL stab.  */
 
 static void
@@ -549,15 +634,19 @@ dbxout_start_source_file (unsigned int line ATTRIBUTE_UNUSED,
                          const char *filename ATTRIBUTE_UNUSED)
 {
 #ifdef DBX_USE_BINCL
-  struct dbx_file *n = (struct dbx_file *) ggc_alloc (sizeof *n);
+  struct dbx_file *n = xmalloc (sizeof *n);
 
   n->next = current_file;
-  n->file_number = next_file_number++;
   n->next_type_number = 1;
+  /* Do not assign file number now. 
+     Delay it until we actually emit BINCL.  */
+  n->file_number = 0;
+  n->prev = NULL;
+  current_file->prev = n;
+  n->bincl_status = BINCL_PENDING;
+  n->pending_bincl_name = filename;
+  pending_bincls = 1;
   current_file = n;
-  fprintf (asmfile, "%s", ASM_STABS_OP);
-  output_quoted_string (asmfile, filename);
-  fprintf (asmfile, ",%d,0,0,0\n", N_BINCL);
 #endif
 }
 
@@ -567,7 +656,10 @@ static void
 dbxout_end_source_file (unsigned int line ATTRIBUTE_UNUSED)
 {
 #ifdef DBX_USE_BINCL
-  fprintf (asmfile, "%s%d,0,0,0\n", ASM_STABN_OP, N_EINCL);
+  /* Emit EINCL stab only if BINCL is not pending.  */
+  if (current_file->bincl_status == BINCL_PROCESSED)
+    fprintf (asmfile, "%s%d,0,0,0\n", ASM_STABN_OP, N_EINCL);
+  current_file->bincl_status = BINCL_NOT_REQUIRED;
   current_file = current_file->next;
 #endif
 }
@@ -652,6 +744,7 @@ dbxout_source_line (unsigned int lineno, const char *filename)
 static void
 dbxout_begin_block (unsigned int line ATTRIBUTE_UNUSED, unsigned int n)
 {
+  emit_pending_bincls_if_required ();
   (*targetm.asm_out.internal_label) (asmfile, "LBB", n);
 }
 
@@ -660,6 +753,7 @@ dbxout_begin_block (unsigned int line ATTRIBUTE_UNUSED, unsigned int n)
 static void
 dbxout_end_block (unsigned int line ATTRIBUTE_UNUSED, unsigned int n)
 {
+  emit_pending_bincls_if_required ();
   (*targetm.asm_out.internal_label) (asmfile, "LBE", n);
 }
 
@@ -672,6 +766,7 @@ dbxout_end_block (unsigned int line ATTRIBUTE_UNUSED, unsigned int n)
 static void
 dbxout_function_decl (tree decl)
 {
+  emit_pending_bincls_if_required ();
 #ifndef DBX_FUNCTION_FIRST
   dbxout_begin_function (decl);
 #endif
@@ -719,60 +814,6 @@ dbxout_finish (const char *filename ATTRIBUTE_UNUSED)
   debug_free_queue ();
 }
 
-/* Output floating point type values used by the 'R' stab letter.
-   These numbers come from include/aout/stab_gnu.h in binutils/gdb.
-
-   There are only 3 real/complex types defined, and we need 7/6.
-   We use NF_SINGLE as a generic float type, and NF_COMPLEX as a generic
-   complex type.  Since we have the type size anyways, we don't really need
-   to distinguish between different FP types, we only need to distinguish
-   between float and complex.  This works fine with gdb.
-
-   We only use this for complex types, to avoid breaking backwards
-   compatibility for real types.  complex types aren't in ISO C90, so it is
-   OK if old debuggers don't understand the debug info we emit for them.  */
-
-/* ??? These are supposed to be IEEE types, but we don't check for that.
-   We could perhaps add additional numbers for non-IEEE types if we need
-   them.  */
-
-static void
-dbxout_fptype_value (tree type)
-{
-  char value = '0';
-  enum machine_mode mode = TYPE_MODE (type);
-
-  if (TREE_CODE (type) == REAL_TYPE)
-    {
-      if (mode == SFmode)
-       value = '1';
-      else if (mode == DFmode)
-       value = '2';
-      else if (mode == TFmode || mode == XFmode)
-       value = '6';
-      else
-       /* Use NF_SINGLE as a generic real type for other sizes.  */
-       value = '1';
-    }
-  else if (TREE_CODE (type) == COMPLEX_TYPE)
-    {
-      if (mode == SCmode)
-       value = '3';
-      else if (mode == DCmode)
-       value = '4';
-      else if (mode == TCmode || mode == XCmode)
-       value = '5';
-      else
-       /* Use NF_COMPLEX as a generic complex type for other sizes.  */
-       value = '3';
-    }
-  else
-    abort ();
-
-  putc (value, asmfile);
-  CHARS (1);
-}
-
 /* Output the index of a type.  */
 
 static void
@@ -798,6 +839,7 @@ dbxout_type_index (tree type)
 static void
 dbxout_continue (void)
 {
+  emit_pending_bincls_if_required ();
 #ifdef DBX_CONTIN_CHAR
   fprintf (asmfile, "%c", DBX_CONTIN_CHAR);
 #else
@@ -1174,15 +1216,13 @@ dbxout_type (tree type, int full)
       if (next_type_number == typevec_len)
        {
          typevec
-           = (struct typeinfo *) ggc_realloc (typevec,
-                                              (typevec_len * 2
-                                               * sizeof typevec[0]));
-         memset ((char *) (typevec + typevec_len), 0,
-                typevec_len * sizeof typevec[0]);
+           = ggc_realloc (typevec, (typevec_len * 2 * sizeof typevec[0]));
+         memset (typevec + typevec_len, 0, typevec_len * sizeof typevec[0]);
          typevec_len *= 2;
        }
 
 #ifdef DBX_USE_BINCL
+      emit_pending_bincls_if_required ();
       typevec[TYPE_SYMTAB_ADDRESS (type)].file_number
        = current_file->file_number;
       typevec[TYPE_SYMTAB_ADDRESS (type)].type_number
@@ -1456,15 +1496,14 @@ dbxout_type (tree type, int full)
       break;
 
     case COMPLEX_TYPE:
-      /* Differs from the REAL_TYPE by its new data type number */
+      /* Differs from the REAL_TYPE by its new data type number.
+        R3 is NF_COMPLEX.  We don't try to use any of the other NF_*
+        codes since gdb doesn't care anyway.  */
 
       if (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE)
        {
-         putc ('R', asmfile);
-         CHARS (1);
-         dbxout_fptype_value (type);
-         putc (';', asmfile);
-         CHARS (1);
+         fputs ("R3;", asmfile);
+         CHARS (3);
          print_wide_int (2 * int_size_in_bytes (TREE_TYPE (type)));
          fputs (";0;", asmfile);
          CHARS (3);
@@ -1667,9 +1706,7 @@ dbxout_type (tree type, int full)
                                * BITS_PER_UNIT);
                putc (',', asmfile);
                CHARS (1);
-               print_wide_int (tree_low_cst (DECL_SIZE
-                                             (TYPE_NAME
-                                              (BINFO_TYPE (child))),
+               print_wide_int (tree_low_cst (TYPE_SIZE (BINFO_TYPE (child)),
                                              0)
                                * BITS_PER_UNIT);
                putc (';', asmfile);
@@ -1977,6 +2014,8 @@ dbxout_class_name_qualifiers (tree decl)
     {
       tree name = TYPE_NAME (context);
 
+      emit_pending_bincls_if_required ();
+
       if (TREE_CODE (name) == TYPE_DECL)
        {
          dbxout_class_name_qualifiers (name);
@@ -2014,7 +2053,7 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED)
       || DECL_IGNORED_P (decl))
     DBXOUT_DECR_NESTING_AND_RETURN (0);
 
-  /* If we are to generate only the symbols actualy used then such
+  /* If we are to generate only the symbols actually used then such
      symbol nodees are flagged with TREE_USED.  Ignore any that
      aren't flaged as TREE_USED.  */
 
@@ -2069,6 +2108,8 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED)
         debug_queue_symbol (TYPE_NAME (t));
     }
 
+  emit_pending_bincls_if_required ();
+
   dbxout_prepare_symbol (decl);
 
   /* The output will always start with the symbol name,
@@ -2341,6 +2382,8 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home)
   int letter = 0;
   int regno = -1;
 
+  emit_pending_bincls_if_required ();
+
   /* Don't mention a variable at all
      if it was completely optimized into nothingness.
 
@@ -2654,6 +2697,8 @@ dbxout_parms (tree parms)
 {
   ++debug_nesting;
 
+  emit_pending_bincls_if_required ();
+
   for (; parms; parms = TREE_CHAIN (parms))
     if (DECL_NAME (parms) && TREE_TYPE (parms) != error_mark_node)
       {