* nlm/gdbserve.c (handle_exception): #if out call to StopBell,
[deliverable/binutils-gdb.git] / gdb / buildsym.c
index 48b1a82374270b628116de0feba682d918007ef0..45ee77affedc52cc0d2608b926ea8fbd5ffd0853 100644 (file)
@@ -31,6 +31,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "symtab.h"
 #include "symfile.h"           /* Needed for "struct complaint" */
 #include "objfiles.h"
+#include "gdbtypes.h"
 #include "complaints.h"
 #include <string.h>
 
@@ -39,6 +40,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "buildsym.h"          /* Our own declarations */
 #undef EXTERN
 
+/* For cleanup_undefined_types and finish_global_stabs (somewhat
+   questionable--see comment where we call them).  */
+#include "stabsread.h"
+
 static int
 compare_line_numbers PARAMS ((const void *, const void *));
 
@@ -62,7 +67,7 @@ struct complaint innerblock_anon_complaint =
   {"inner block not inside outer block", 0, 0};
 
 struct complaint blockvector_complaint = 
-  {"block at 0x%x out of order", 0, 0};
+  {"block at 0x%lx out of order", 0, 0};
 
 \f
 /* maintain the lists of symbols and blocks */
@@ -222,8 +227,49 @@ finish_block (symbol, listhead, old_blocks, start, end, objfile)
 
   if (symbol)
     {
+      struct type *ftype = SYMBOL_TYPE (symbol);
       SYMBOL_BLOCK_VALUE (symbol) = block;
       BLOCK_FUNCTION (block) = symbol;
+
+      if (TYPE_NFIELDS (ftype) <= 0)
+       {
+         /* No parameter type information is recorded with the function's
+            type.  Set that from the type of the parameter symbols. */
+         int nparams = 0, iparams;
+         struct symbol *sym;
+         for (i = 0; i < BLOCK_NSYMS (block); i++)
+           {
+             sym = BLOCK_SYM (block, i);
+             switch (SYMBOL_CLASS (sym))
+               {
+               case LOC_ARG:
+               case LOC_REF_ARG:
+               case LOC_REGPARM:
+               case LOC_REGPARM_ADDR:
+                 nparams++;
+               }
+           }
+         if (nparams > 0)
+           {
+             TYPE_NFIELDS (ftype) = nparams;
+             TYPE_FIELDS (ftype) = (struct field *)
+               TYPE_ALLOC (ftype, nparams * sizeof (struct field));
+                                               
+             for (i = iparams = 0; iparams < nparams; i++)
+               {
+                 sym = BLOCK_SYM (block, i);
+                 switch (SYMBOL_CLASS (sym))
+                   {
+                   case LOC_ARG:
+                   case LOC_REF_ARG:
+                   case LOC_REGPARM:
+                   case LOC_REGPARM_ADDR:
+                     TYPE_FIELD_TYPE (ftype, iparams) = SYMBOL_TYPE (sym);
+                     iparams++;
+                   }
+               }
+           }
+       }
     }
   else
     {
@@ -347,8 +393,17 @@ make_blockvector (objfile)
          if (BLOCK_START(BLOCKVECTOR_BLOCK (blockvector, i-1))
              > BLOCK_START(BLOCKVECTOR_BLOCK (blockvector, i)))
            {
+
+             /* FIXME-32x64: loses if CORE_ADDR doesn't fit in a
+                long.  Possible solutions include a version of
+                complain which takes a callback, a
+                sprintf_address_numeric to match
+                print_address_numeric, or a way to set up a GDB_FILE
+                * which causes sprintf rather than fprintf to be
+                called.  */
+
              complain (&blockvector_complaint, 
-                       BLOCK_START(BLOCKVECTOR_BLOCK (blockvector, i)));
+                       (unsigned long) BLOCK_START(BLOCKVECTOR_BLOCK (blockvector, i)));
            }
        }
     }
@@ -392,8 +447,9 @@ start_subfile (name, dirname)
   current_subfile = subfile;
 
   /* Save its name and compilation directory name */
-  subfile->name = (name == NULL)? NULL : strdup (name);
-  subfile->dirname = (dirname == NULL) ? NULL : strdup (dirname);
+  subfile->name = (name == NULL) ? NULL : savestring (name, strlen (name));
+  subfile->dirname =
+    (dirname == NULL) ? NULL : savestring (dirname, strlen (dirname));
   
   /* Initialize line-number recording for this subfile.  */
   subfile->line_vector = NULL;
@@ -422,29 +478,29 @@ start_subfile (name, dirname)
      directives which specify a file name ending in .C.
 
      So if the filename of this subfile ends in .C, then change the language
-     of any pending subfiles from C to C++.  .cc is also accepted, even
-     though I don't think cfront allows it.  */
+     of any pending subfiles from C to C++.  We also accept any other C++
+     suffixes accepted by deduce_language_from_filename (in particular,
+     some people use .cxx with cfront).  */
+  /* Likewise for f2c.  */
 
   if (subfile->name)
     {
-      char *p;
       struct subfile *s;
+      enum language sublang = deduce_language_from_filename (subfile->name);
 
-      p = strrchr (subfile->name, '.');
-      if (p != NULL
-         && ((p[1] == 'C' && p[2] == '\0')
-             || (p[1] == 'c' && p[2] == 'c' && p[3] == '\0')))
+      if (sublang == language_cplus || sublang == language_fortran)
        for (s = subfiles; s != NULL; s = s->next)
          if (s->language == language_c)
-           s->language = language_cplus;
+           s->language = sublang;
     }
 
   /* And patch up this file if necessary.  */
   if (subfile->language == language_c
       && subfile->next != NULL
-      && subfile->next->language == language_cplus)
+      && (subfile->next->language == language_cplus
+         || subfile->next->language == language_fortran))
     {
-      subfile->language = language_cplus;
+      subfile->language = subfile->next->language;
     }
 }
 
@@ -469,7 +525,7 @@ patch_subfile_names (subfile, name)
       && subfile->name[strlen(subfile->name)-1] == '/')
     {
       subfile->dirname = subfile->name;
-      subfile->name = strdup (name);
+      subfile->name = savestring (name, strlen (name));
 
       /* Default the source language to whatever can be deduced from
         the filename.  If nothing can be deduced (such as for a C/C++
@@ -653,7 +709,7 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile, section)
      struct objfile *objfile;
      int section;
 {
-  register struct symtab *symtab;
+  register struct symtab *symtab = NULL;
   register struct blockvector *blockvector;
   register struct subfile *subfile;
   register struct context_stack *cstk;
@@ -670,11 +726,16 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile, section)
       finish_block (cstk->name, &local_symbols, cstk->old_blocks,
                    cstk->start_addr, end_addr, objfile);
 
-      /* Debug: if context stack still has something in it,
-        we are in trouble.  */
       if (context_stack_depth > 0)
        {
-         abort ();
+         /* This is said to happen with SCO.  The old coffread.c code
+            simply emptied the context stack, so we do the same.  FIXME:
+            Find out why it is happening.  This is not believed to happen
+            in most cases (even for coffread.c); it used to be an abort().  */
+         static struct complaint msg =
+           {"Context stack not empty in end_symtab", 0, 0};
+         complain (&msg);
+         context_stack_depth = 0;
        }
     }
 
@@ -751,7 +812,7 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile, section)
 
   for (subfile = subfiles; subfile; subfile = nextsub)
     {
-      int linetablesize;
+      int linetablesize = 0;
       /* If we have blocks of symbols, make a symtab.
         Otherwise, just ignore this file and any line number info in it.  */
       symtab = NULL;
This page took 0.025848 seconds and 4 git commands to generate.