OSDN Git Service

* include/ext/pool_allocator.h: Include c++config.h.
[pf3gnuchains/gcc-fork.git] / gcc / dbxout.c
index 4265c9c..e020d03 100644 (file)
@@ -1,6 +1,6 @@
 /* Output dbx-format symbol table information from GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -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);
@@ -358,23 +382,26 @@ const struct gcc_debug_hooks dbx_debug_hooks =
   dbxout_end_source_file,
   dbxout_begin_block,
   dbxout_end_block,
-  debug_true_tree,             /* ignore_block */
-  dbxout_source_line,          /* source_line */
-  dbxout_source_line,          /* begin_prologue: just output line info */
-  debug_nothing_int_charstar,  /* end_prologue */
-  debug_nothing_int_charstar,  /* end_epilogue */
+  debug_true_tree,                      /* ignore_block */
+  dbxout_source_line,                   /* source_line */
+  dbxout_source_line,                   /* begin_prologue: just output 
+                                           line info */
+  debug_nothing_int_charstar,           /* end_prologue */
+  debug_nothing_int_charstar,           /* end_epilogue */
 #ifdef DBX_FUNCTION_FIRST
   dbxout_begin_function,
 #else
-  debug_nothing_tree,          /* begin_function */
+  debug_nothing_tree,                   /* begin_function */
 #endif
-  debug_nothing_int,           /* end_function */
+  debug_nothing_int,                    /* end_function */
   dbxout_function_decl,
-  dbxout_global_decl,          /* global_decl */
-  debug_nothing_tree,          /* deferred_inline_function */
-  debug_nothing_tree,          /* outlining_inline_function */
-  debug_nothing_rtx,           /* label */
-  dbxout_handle_pch            /* handle_pch */
+  dbxout_global_decl,                   /* global_decl */
+  debug_nothing_tree_tree,               /* imported_module_or_decl */
+  debug_nothing_tree,                   /* deferred_inline_function */
+  debug_nothing_tree,                   /* outlining_inline_function */
+  debug_nothing_rtx,                    /* label */
+  dbxout_handle_pch,                    /* handle_pch */
+  debug_nothing_rtx                     /* var_location */
 };
 #endif /* DBX_DEBUGGING_INFO  */
 
@@ -389,19 +416,21 @@ const struct gcc_debug_hooks xcoff_debug_hooks =
   dbxout_end_source_file,
   xcoffout_begin_block,
   xcoffout_end_block,
-  debug_true_tree,             /* ignore_block */
+  debug_true_tree,                      /* ignore_block */
   xcoffout_source_line,
-  xcoffout_begin_prologue,     /* begin_prologue */
-  debug_nothing_int_charstar,  /* end_prologue */
+  xcoffout_begin_prologue,              /* begin_prologue */
+  debug_nothing_int_charstar,           /* end_prologue */
   xcoffout_end_epilogue,
-  debug_nothing_tree,          /* begin_function */
+  debug_nothing_tree,                   /* begin_function */
   xcoffout_end_function,
-  debug_nothing_tree,          /* function_decl */
-  dbxout_global_decl,          /* global_decl */
-  debug_nothing_tree,          /* deferred_inline_function */
-  debug_nothing_tree,          /* outlining_inline_function */
-  debug_nothing_rtx,           /* label */
-  dbxout_handle_pch            /* handle_pch */
+  debug_nothing_tree,                   /* function_decl */
+  dbxout_global_decl,                   /* global_decl */
+  debug_nothing_tree_tree,               /* imported_module_or_decl */
+  debug_nothing_tree,                   /* deferred_inline_function */
+  debug_nothing_tree,                   /* outlining_inline_function */
+  debug_nothing_rtx,                    /* label */
+  dbxout_handle_pch,                    /* handle_pch */
+  debug_nothing_rtx                     /* var_location */
 };
 #endif /* XCOFF_DEBUGGING_INFO  */
 \f
@@ -443,7 +472,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 +482,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 +527,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 +548,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 +639,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 +661,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 +749,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 +758,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 +771,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 +819,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 +844,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
@@ -822,6 +869,11 @@ dbxout_type_fields (tree type)
      field that we can support.  */
   for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
     {
+
+      /* If on of the nodes is an error_mark or its type is then return early. */
+      if (tem == error_mark_node || TREE_TYPE (tem) == error_mark_node)
+       return;
+
       /* Omit here local type decls until we know how to support them.  */
       if (TREE_CODE (tem) == TYPE_DECL
          /* Omit fields whose position or size are variable or too large to
@@ -1174,15 +1226,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 +1506,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);
@@ -1634,8 +1683,10 @@ dbxout_type (tree type, int full)
            if (use_gnu_debug_info_extensions)
              {
                have_used_extensions = 1;
-               putc (TREE_VIA_VIRTUAL (child) ? '1' : '0', asmfile);
-               putc (access == access_public_node ? '2' : '0', asmfile);
+                putc (TREE_VIA_VIRTUAL (child) ? '1' : '0', asmfile);
+                putc (access == access_public_node ? '2' :
+                      (access == access_protected_node ? '1' :'0'),
+                      asmfile);
                CHARS (2);
                if (TREE_VIA_VIRTUAL (child)
                    && strcmp (lang_hooks.name, "GNU C++") == 0)
@@ -1667,9 +1718,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 +2026,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);
@@ -2003,18 +2054,13 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED)
   /* "Intercept" dbxout_symbol() calls like we do all debug_hooks.  */
   ++debug_nesting;
 
-  /* Cast avoids warning in old compilers.  */
-  current_sym_code = (STAB_CODE_TYPE) 0;
-  current_sym_value = 0;
-  current_sym_addr = 0;
-
   /* Ignore nameless syms, but don't ignore type tags.  */
 
   if ((DECL_NAME (decl) == 0 && TREE_CODE (decl) != TYPE_DECL)
       || 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 +2115,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,
@@ -2306,7 +2354,7 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED)
                }
              else if (TREE_CODE (TREE_TYPE (decl)) == REAL_TYPE)
                {
-                 /* don't know how to do this yet.  */
+                 /* Don't know how to do this yet.  */
                }
              break;
            }
@@ -2341,6 +2389,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.
 
@@ -2530,10 +2580,6 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home)
       else
        dbxout_symbol_location (decl, subtype, "$real", XEXP (home, 0));
 
-      /* Cast avoids warning in old compilers.  */
-      current_sym_code = (STAB_CODE_TYPE) 0;
-      current_sym_value = 0;
-      current_sym_addr = 0;
       dbxout_prepare_symbol (decl);
 
       if (WORDS_BIG_ENDIAN)
@@ -2573,9 +2619,11 @@ dbxout_symbol_name (tree decl, const char *suffix, int letter)
 {
   const char *name;
 
-  if (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
-    /* One slight hitch: if this is a VAR_DECL which is a static
-       class member, we must put out the mangled name instead of the
+  if (DECL_CONTEXT (decl) 
+      && (TYPE_P (DECL_CONTEXT (decl))
+         || TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL))
+    /* One slight hitch: if this is a VAR_DECL which is a class member
+       or a namespace member, we must put out the mangled name instead of the
        DECL_NAME.  Note also that static member (variable) names DO NOT begin
        with underscores in .stabs directives.  */
     name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
@@ -2601,6 +2649,14 @@ dbxout_prepare_symbol (tree decl ATTRIBUTE_UNUSED)
 
   dbxout_source_file (asmfile, filename);
 #endif
+
+  /* Initialize variables used to communicate each symbol's debug
+     information to dbxout_finish_symbol with zeroes.  */
+
+  /* Cast avoids warning in old compilers.  */
+  current_sym_code = (STAB_CODE_TYPE) 0;
+  current_sym_value = 0;
+  current_sym_addr = 0;
 }
 
 static void
@@ -2654,6 +2710,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)
       {