* serial.h (SERIAL_SET_TTY_STATE): Comment return value.
[deliverable/binutils-gdb.git] / gdb / symtab.c
index 38675d13ba9ebcafbdb98330ad3085e718c8180c..3e751db5e693b612768846516456faa8f52dc806 100644 (file)
@@ -1,6 +1,6 @@
 /* Symbol table lookup for the GNU debugger, GDB.
-   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992
-   Free Software Foundation, Inc.
+   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994
+             Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -111,8 +111,8 @@ void
 cplusplus_hint (name)
      char *name;
 {
-  printf ("Hint: try '%s<TAB> or '%s<ESC-?>\n", name, name);
-  printf ("(Note leading single quote.)\n");
+  printf_unfiltered ("Hint: try '%s<TAB> or '%s<ESC-?>\n", name, name);
+  printf_unfiltered ("(Note leading single quote.)\n");
 }
 
 /* Check for a symtab of a specific name; first in symtabs, then in
@@ -156,26 +156,9 @@ lookup_symtab_1 (name)
   /* Same search rules as above apply here, but now we look thru the
      psymtabs.  */
 
-  ALL_PSYMTABS (objfile, ps)
-    if (STREQ (name, ps -> filename))
-      goto got_psymtab;
-
-  if (!slash)
-    ALL_PSYMTABS (objfile, ps)
-      {
-       char *p = ps -> filename;
-       char *tail = strrchr (p, '/');
-
-       if (tail)
-         p = tail + 1;
-
-       if (STREQ (p, name))
-         goto got_psymtab;
-      }
-
-  return (NULL);
-
- got_psymtab:
+  ps = lookup_partial_symtab (name);
+  if (!ps)
+    return (NULL);
 
   if (ps -> readin)
     error ("Internal: readin %s pst for `%s' found when no symtab found.",
@@ -210,21 +193,29 @@ lookup_symtab (name)
   s = lookup_symtab_1 (name);
   if (s) return s;
 
+#if 0
+  /* This screws c-exp.y:yylex if there is both a type "tree" and a symtab
+     "tree.c".  */
+
   /* If name not found as specified, see if adding ".c" helps.  */
+  /* Why is this?  Is it just a user convenience?  (If so, it's pretty
+     questionable in the presence of C++, FORTRAN, etc.).  It's not in
+     the GDB manual.  */
 
   copy = (char *) alloca (strlen (name) + 3);
   strcpy (copy, name);
   strcat (copy, ".c");
   s = lookup_symtab_1 (copy);
   if (s) return s;
+#endif /* 0 */
 
   /* We didn't find anything; die.  */
   return 0;
 }
 
-/* Lookup the partial symbol table of a source file named NAME.  This
-   only returns true on an exact match (ie. this semantics are
-   different from lookup_symtab.  */
+/* Lookup the partial symbol table of a source file named NAME.
+   *If* there is no '/' in the name, a match after a '/'
+   in the psymtab filename will also work.  */
 
 struct partial_symtab *
 lookup_partial_symtab (name)
@@ -240,6 +231,22 @@ char *name;
          return (pst);
        }
     }
+
+  /* Now, search for a matching tail (only if name doesn't have any dirs) */
+
+  if (!strchr (name, '/'))
+    ALL_PSYMTABS (objfile, pst)
+      {
+       char *p = pst -> filename;
+       char *tail = strrchr (p, '/');
+
+       if (tail)
+         p = tail + 1;
+
+       if (STREQ (p, name))
+         return (pst);
+      }
+
   return (NULL);
 }
 \f
@@ -258,23 +265,48 @@ gdb_mangle_name (type, i, j)
   char *field_name = TYPE_FN_FIELDLIST_NAME (type, i);
   char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
   char *newname = type_name_no_tag (type);
-  int is_constructor = newname != NULL && STREQ (field_name, newname);
-  int is_destructor = is_constructor && DESTRUCTOR_PREFIX_P (physname);
+
+  /* Does the form of physname indicate that it is the full mangled name
+     of a constructor (not just the args)?  */
+  int is_full_physname_constructor;
+
+  int is_constructor;
+  int is_destructor = DESTRUCTOR_PREFIX_P (physname);
   /* Need a new type prefix.  */
   char *const_prefix = method->is_const ? "C" : "";
   char *volatile_prefix = method->is_volatile ? "V" : "";
   char buf[20];
-#ifndef GCC_MANGLE_BUG
-  int len = newname == NULL ? 0 : strlen (newname);
+  int len = (newname == NULL ? 0 : strlen (newname));
 
-  if (is_destructor)
+  is_full_physname_constructor = 
+    ((physname[0]=='_' && physname[1]=='_' && 
+      (isdigit(physname[2]) || physname[2]=='Q' || physname[2]=='t'))
+     || (strncmp(physname, "__ct", 4) == 0));
+
+  is_constructor =
+    is_full_physname_constructor || (newname && STREQ(field_name, newname));
+
+  if (!is_destructor)
+    is_destructor = (strncmp(physname, "__dt", 4) == 0); 
+
+#ifndef GCC_MANGLE_BUG
+  if (is_destructor || is_full_physname_constructor)
     {
       mangled_name = (char*) xmalloc(strlen(physname)+1);
       strcpy(mangled_name, physname);
       return mangled_name;
     }
 
-  sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len);
+  if (len == 0)
+    {
+      sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
+      if (strcmp(buf, "__") == 0)
+       buf[0] = '\0';
+    }
+  else
+    {
+      sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len);
+    }
   mangled_name_len = ((is_constructor ? 0 : strlen (field_name))
                          + strlen (buf) + len
                          + strlen (physname)
@@ -305,11 +337,11 @@ gdb_mangle_name (type, i, j)
   strcat (mangled_name, buf);
   /* If the class doesn't have a name, i.e. newname NULL, then we just
      mangle it using 0 for the length of the class.  Thus it gets mangled
-     as something starting with `::' rather than `classname::'.  */
+     as something starting with `::' rather than `classname::'. */ 
   if (newname != NULL)
     strcat (mangled_name, newname);
+
 #else
-  char *opname;
 
   if (is_constructor)
     {
@@ -327,6 +359,7 @@ gdb_mangle_name (type, i, j)
      work with the normal mechanisms.  */
   if (OPNAME_PREFIX_P (field_name))
     {
+      char *opname;
       opname = cplus_mangle_opname (field_name + 3, 0);
       if (opname == NULL)
        {
@@ -382,7 +415,7 @@ find_pc_psymbol (psymtab, pc)
      struct partial_symtab *psymtab;
      CORE_ADDR pc;
 {
-  struct partial_symbol *best, *p;
+  struct partial_symbol *best = NULL, *p;
   CORE_ADDR best_pc;
   
   if (!psymtab)
@@ -392,6 +425,21 @@ find_pc_psymbol (psymtab, pc)
 
   best_pc = psymtab->textlow - 1;
 
+  /* Search the global symbols as well as the static symbols, so that
+     find_pc_partial_function doesn't use a minimal symbol and thus
+     cache a bad endaddr.  */
+  for (p = psymtab->objfile->global_psymbols.list + psymtab->globals_offset;
+       (p - (psymtab->objfile->global_psymbols.list + psymtab->globals_offset)
+       < psymtab->n_global_syms);
+       p++)
+    if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE
+       && SYMBOL_CLASS (p) == LOC_BLOCK
+       && pc >= SYMBOL_VALUE_ADDRESS (p)
+       && SYMBOL_VALUE_ADDRESS (p) > best_pc)
+      {
+       best_pc = SYMBOL_VALUE_ADDRESS (p);
+       best = p;
+      }
   for (p = psymtab->objfile->static_psymbols.list + psymtab->statics_offset;
        (p - (psymtab->objfile->static_psymbols.list + psymtab->statics_offset)
        < psymtab->n_static_syms);
@@ -421,6 +469,16 @@ find_pc_psymbol (psymtab, pc)
    BLOCK_FOUND is set to the block in which NAME is found (in the case of
    a field of `this', value_of_this sets BLOCK_FOUND to the proper value.) */
 
+/* This function has a bunch of loops in it and it would seem to be
+   attractive to put in some QUIT's (though I'm not really sure
+   whether it can run long enough to be really important).  But there
+   are a few calls for which it would appear to be bad news to quit
+   out of here: find_proc_desc in alpha-tdep.c and mips-tdep.c, and
+   nindy_frame_chain_valid in nindy-tdep.c.  (Note that there is C++
+   code below which can error(), but that probably doesn't affect
+   these calls since they are looking for a known variable and thus
+   can probably assume it will never hit the C++ code).  */
+
 struct symbol *
 lookup_symbol (name, block, namespace, is_a_field_of_this, symtab)
      const char *name;
@@ -430,14 +488,12 @@ lookup_symbol (name, block, namespace, is_a_field_of_this, symtab)
      struct symtab **symtab;
 {
   register struct symbol *sym;
-  register struct symtab *s;
+  register struct symtab *s = NULL;
   register struct partial_symtab *ps;
   struct blockvector *bv;
   register struct objfile *objfile;
   register struct block *b;
   register struct minimal_symbol *msymbol;
-  char *temp;
-  extern char *gdb_completer_word_break_characters;
 
   /* Search specified block and its superiors.  */
 
@@ -899,7 +955,8 @@ lookup_block_symbol (block, name, namespace)
                  SYMBOL_CLASS (sym) != LOC_LOCAL_ARG &&
                  SYMBOL_CLASS (sym) != LOC_REF_ARG &&
                  SYMBOL_CLASS (sym) != LOC_REGPARM &&
-                 SYMBOL_CLASS (sym) != LOC_REGPARM_ADDR)
+                 SYMBOL_CLASS (sym) != LOC_REGPARM_ADDR &&
+                 SYMBOL_CLASS (sym) != LOC_BASEREG_ARG)
                {
                  break;
                }
@@ -973,11 +1030,86 @@ find_pc_symtab (pc)
           will cause a core dump), but maybe we can successfully
           continue, so let's not.  */
        warning ("\
-(Internal error: pc 0x%x in read in psymtab, but not in symtab.)\n", pc);
+(Internal error: pc 0x%lx in read in psymtab, but not in symtab.)\n",
+                (unsigned long) pc);
       s = PSYMTAB_TO_SYMTAB (ps);
     }
   return (s);
 }
+\f
+/* Find the closest symbol value (of any sort -- function or variable)
+   for a given address value.  Slow but complete.  */
+
+struct symbol *
+find_addr_symbol (addr, symtabp, symaddrp)
+     CORE_ADDR addr;
+     struct symtab **symtabp;
+     CORE_ADDR *symaddrp;
+{
+  struct symtab *symtab, *best_symtab;
+  struct objfile *objfile;
+  register int bot, top;
+  register struct symbol *sym;
+  register CORE_ADDR sym_addr;
+  struct block *block;
+  int blocknum;
+
+  /* Info on best symbol seen so far */
+
+  register CORE_ADDR best_sym_addr = 0;
+  struct symbol *best_sym = 0;
+
+  /* FIXME -- we should pull in all the psymtabs, too!  */
+  ALL_SYMTABS (objfile, symtab)
+    {
+      /* Search the global and static blocks in this symtab for
+        the closest symbol-address to the desired address.  */
+
+      for (blocknum = GLOBAL_BLOCK; blocknum <= STATIC_BLOCK; blocknum++)
+       {
+         QUIT;
+         block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), blocknum);
+         top = BLOCK_NSYMS (block);
+         for (bot = 0; bot < top; bot++)
+           {
+             sym = BLOCK_SYM (block, bot);
+             switch (SYMBOL_CLASS (sym))
+               {
+               case LOC_STATIC:        
+               case LOC_LABEL: 
+                 sym_addr = SYMBOL_VALUE_ADDRESS (sym);
+                 break;
+
+               case LOC_BLOCK:
+                 sym_addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+                 break;
+
+               default:
+                 continue;
+               }
+
+               if (sym_addr <= addr)
+                 if (sym_addr > best_sym_addr)
+                   {
+                     /* Quit if we found an exact match.  */
+                     best_sym = sym;
+                     best_sym_addr = sym_addr;
+                     best_symtab = symtab;
+                     if (sym_addr == addr)
+                       goto done;
+                   }
+           }
+       }
+    }
+
+ done:
+  if (symtabp)
+    *symtabp = best_symtab;
+  if (symaddrp)
+    *symaddrp = best_sym_addr;
+  return best_sym;
+}
+
 
 /* Find the source file and line number for a given PC value.
    Return a structure containing a symtab pointer, a line number,
@@ -992,15 +1124,9 @@ find_pc_symtab (pc)
    code in the middle of a subroutine.  To properly find the end of a line's PC
    range, we must search all symtabs associated with this compilation unit, and
    find the one whose first PC is closer than that of the next line in this
-   symtab.
-
-   FIXME:  We used to complain here about zero length or negative length line
-   tables, but there are two problems with this: (1) some symtabs may not have
-   any line numbers due to gcc -g1 compilation, and (2) this function is called
-   during single stepping, when we don't own the terminal and thus can't
-   produce any output.  One solution might be to implement a mechanism whereby
-   complaints can be queued until we regain control of the terminal.  -fnf
- */
+   symtab.  */
+
+/* If it's worth the effort, we could be using a binary search.  */
 
 struct symtab_and_line
 find_pc_line (pc, notcurrent)
@@ -1064,8 +1190,12 @@ find_pc_line (pc, notcurrent)
       if (!l)
         continue;
       len = l->nitems;
-      if (len <= 0)              /* See FIXME above. */
+      if (len <= 0)
        {
+         /* I think len can be zero if the symtab lacks line numbers
+            (e.g. gcc -g1).  (Either that or the LINETABLE is NULL;
+            I'm not sure which, and maybe it depends on the symbol
+            reader).  */
          continue;
        }
 
@@ -1261,37 +1391,41 @@ find_line_pc (symtab, line)
    Returns 0 if could not find the specified line.  */
 
 int
-find_line_pc_range (symtab, thisline, startptr, endptr)
-     struct symtab *symtab;
-     int thisline;
+find_line_pc_range (sal, startptr, endptr)
+     struct symtab_and_line sal;
      CORE_ADDR *startptr, *endptr;
 {
-  struct linetable *l;
-  int ind;
-  int exact_match;             /* did we get an exact linenumber match */
+  CORE_ADDR startaddr;
+  struct symtab_and_line found_sal;
 
-  if (symtab == 0)
+  startaddr = sal.pc;
+  if (startaddr == 0)
+    {
+      startaddr = find_line_pc (sal.symtab, sal.line);
+    }
+  if (startaddr == 0)
     return 0;
 
-  if (find_line_symtab (symtab, thisline, &l, &ind, &exact_match))
+  /* This whole function is based on address.  For example, if line 10 has
+     two parts, one from 0x100 to 0x200 and one from 0x300 to 0x400, then
+     "info line *0x123" should say the line goes from 0x100 to 0x200
+     and "info line *0x355" should say the line goes from 0x300 to 0x400.
+     This also insures that we never give a range like "starts at 0x134
+     and ends at 0x12c".  */
+
+  found_sal = find_pc_line (startaddr, 0);
+  if (found_sal.line != sal.line)
     {
-      *startptr = l->item[ind].pc;
-      /* If we have not seen an entry for the specified line,
-        assume that means the specified line has zero bytes.  */
-      if (!exact_match || ind == l->nitems-1)
-       *endptr = *startptr;
-      else
-       /* Perhaps the following entry is for the following line.
-          It's worth a try.  */
-       if (ind+1 < l->nitems
-        && l->item[ind+1].line == thisline + 1)
-         *endptr = l->item[ind+1].pc;
-       else
-         *endptr = find_line_pc (symtab, thisline+1);
-      return 1;
+      /* The specified line (sal) has zero bytes.  */
+      *startptr = found_sal.pc;
+      *endptr = found_sal.pc;
     }
-
-  return 0;
+  else
+    {
+      *startptr = found_sal.pc;
+      *endptr = found_sal.end;
+    }
+  return 1;
 }
 
 /* Given a line table and a line number, return the index into the line
@@ -1328,6 +1462,7 @@ find_line_common (l, lineno, exact_match)
 
       if (item->line == lineno)
        {
+         /* Return the first (lowest address) entry which matches.  */
          *exact_match = 1;
          return i;
        }
@@ -1461,24 +1596,9 @@ find_methods (t, name, sym_arr)
   int ibase;
   struct symbol *sym_class;
   char *class_name = type_name_no_tag (t);
-  /* Ignore this class if it doesn't have a name.
-     This prevents core dumps, but is just a workaround
-     because we might not find the function in
-     certain cases, such as
-     struct D {virtual int f();}
-     struct C : D {virtual int g();}
-     (in this case g++ 1.35.1- does not put out a name
-     for D as such, it defines type 19 (for example) in
-     the same stab as C, and then does a
-     .stabs "D:T19" and a .stabs "D:t19".
-     Thus
-     "break C::f" should not be looking for field f in
-     the class named D, 
-     but just for the field f in the baseclasses of C
-     (no matter what their names).
-     
-     However, I don't know how to replace the code below
-     that depends on knowing the name of D.  */
+  /* Ignore this class if it doesn't have a name.  This is ugly, but
+     unless we figure out how to get the physname without the name of
+     the class, then the loop can't do any good.  */
   if (class_name
       && (sym_class = lookup_symbol (class_name,
                                     (struct block *)NULL,
@@ -1487,6 +1607,7 @@ find_methods (t, name, sym_arr)
                                     (struct symtab **)NULL)))
     {
       int method_counter;
+      /* FIXME: Shouldn't this just be check_stub_type (t)?  */
       t = SYMBOL_TYPE (sym_class);
       for (method_counter = TYPE_NFN_FIELDS (t) - 1;
           method_counter >= 0;
@@ -1494,8 +1615,18 @@ find_methods (t, name, sym_arr)
        {
          int field_counter;
          struct fn_field *f = TYPE_FN_FIELDLIST1 (t, method_counter);
-
          char *method_name = TYPE_FN_FIELDLIST_NAME (t, method_counter);
+         char dem_opname[64];
+
+          if (strncmp(method_name, "__", 2)==0 ||
+           strncmp(method_name, "op", 2)==0 ||
+           strncmp(method_name, "type", 4)==0 )
+           {
+             if (cplus_demangle_opname(method_name, dem_opname, DMGL_ANSI))
+               method_name = dem_opname;
+             else if (cplus_demangle_opname(method_name, dem_opname, 0))
+               method_name = dem_opname; 
+           }
          if (STREQ (name, method_name))
            /* Find all the fields with that name.  */
            for (field_counter = TYPE_FN_FIELDLIST_LENGTH (t, method_counter) - 1;
@@ -1509,6 +1640,14 @@ find_methods (t, name, sym_arr)
                /* Destructor is handled by caller, dont add it to the list */
                if (DESTRUCTOR_PREFIX_P (phys_name))
                  continue;
+
+               /* FIXME: Why are we looking this up in the
+                  SYMBOL_BLOCK_VALUE (sym_class)?  It is intended as a hook
+                  for nested types?  If so, it should probably hook to the
+                  type, not the symbol.  mipsread.c is the only symbol
+                  reader which sets the SYMBOL_BLOCK_VALUE for types, and
+                  this is not documented in symtab.h.  -26Aug93.  */
+
                sym_arr[i1] = lookup_symbol (phys_name,
                                             SYMBOL_BLOCK_VALUE (sym_class),
                                             VAR_NAMESPACE,
@@ -1517,17 +1656,27 @@ find_methods (t, name, sym_arr)
                if (sym_arr[i1]) i1++;
                else
                  {
-                   fputs_filtered("(Cannot find method ", stdout);
-                   fprintf_symbol_filtered (stdout, phys_name,
-                                            language_cplus, DMGL_PARAMS);
-                   fputs_filtered(" - possibly inlined.)\n", stdout);
+                   fputs_filtered("(Cannot find method ", gdb_stdout);
+                   fprintf_symbol_filtered (gdb_stdout, phys_name,
+                                            language_cplus,
+                                            DMGL_PARAMS | DMGL_ANSI);
+                   fputs_filtered(" - possibly inlined.)\n", gdb_stdout);
                  }
              }
        }
     }
-  /* Only search baseclasses if there is no match yet,
-   * since names in derived classes override those in baseclasses.
-   */
+
+  /* Only search baseclasses if there is no match yet, since names in
+     derived classes override those in baseclasses.
+
+     FIXME: The above is not true; it is only true of member functions
+     if they have the same number of arguments (??? - section 13.1 of the
+     ARM says the function members are not in the same scope but doesn't
+     really spell out the rules in a way I understand.  In any case, if
+     the number of arguments differ this is a case in which we can overload
+     rather than hiding without any problem, and gcc 2.4.5 does overload
+     rather than hiding in this case).  */
+
   if (i1)
     return i1;
   for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++)
@@ -1610,6 +1759,11 @@ build_canonical_line_spec (sal, symname, canonical)
    if no file is validly specified.  Callers must check that.
    Also, the line number returned may be invalid.  */
 
+/* We allow single quotes in various places.  This is a hideous
+   kludge, which exists because the completer can't yet deal with the
+   lack of single quotes.  FIXME: write a linespec_completer which we
+   can use as appropriate instead of make_symbol_completion_list.  */
+
 struct symtabs_and_lines
 decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
      char **argptr;
@@ -1650,7 +1804,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
   struct symtab_and_line val;
 #endif
   register char *p, *p1;
-  char *q, *q1;
+  char *q, *q1, *pp;
   register struct symtab *s;
 
   register struct symbol *sym;
@@ -1662,7 +1816,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
   char *copy;
   struct symbol *sym_class;
   int i1;
-  int is_quoted;
+  int is_quoted, has_parens;
   struct symbol **sym_arr;
   struct type *t;
   char *saved_arg = *argptr;
@@ -1697,19 +1851,33 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
   /* Maybe arg is FILE : LINENUM or FILE : FUNCTION */
 
   s = NULL;
-  is_quoted = (strchr (gdb_completer_quote_characters, **argptr) != NULL);
+  is_quoted = (strchr(gdb_completer_quote_characters, **argptr) != NULL);
+  has_parens = (( pp = strchr(*argptr, '(')) != NULL  &&
+                (pp = strchr(pp, ')')) != NULL);
 
   for (p = *argptr; *p; p++)
     {
+      if (p[0] == '<') 
+       {
+         while(!++p && *p != '>');
+         if (!p)
+           {
+             /* FIXME: Why warning() and then return_to_top_level?
+                What's wrong with error()?  */
+             warning("non-matching '<' and '>' in command");
+             return_to_top_level (RETURN_ERROR);
+           }
+       }
       if (p[0] == ':' || p[0] == ' ' || p[0] == '\t')
        break;
     }
   while (p[0] == ' ' || p[0] == '\t') p++;
 
-  if ((p[0] == ':') && !is_quoted)
+  if ((p[0] == ':') && !has_parens)
     {
 
       /*  C++  */
+      if (is_quoted) *argptr = *argptr+1;
       if (p[1] ==':')
        {
          /* Extract the class name.  */
@@ -1732,11 +1900,19 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
               || TYPE_CODE (SYMBOL_TYPE (sym_class)) == TYPE_CODE_UNION))
            {
              /* Arg token is not digits => try it as a function name
-                Find the next token (everything up to end or next whitespace). */
-             p = *argptr;
-             while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p !=':') p++;
+                Find the next token(everything up to end or next blank). */
+             if (strchr(gdb_completer_quote_characters, **argptr) != NULL)
+               {
+                 p = skip_quoted(*argptr);
+                 *argptr = *argptr + 1;
+               }
+             else
+               {
+                 p = *argptr;
+                 while (*p && *p!=' ' && *p!='\t' && *p!=',' && *p!=':') p++;
+               }
+/*
              q = operator_chars (*argptr, &q1);
-
              if (q1 - q)
                {
                  char *opname;
@@ -1755,10 +1931,13 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
                  p = q1;
                }
              else
+*/
                {
-                 copy = (char *) alloca (p - *argptr + 1 + (q1 - q));
+                 copy = (char *) alloca (p - *argptr + 1 );
                  memcpy (copy, *argptr, p - *argptr);
                  copy[p - *argptr] = '\0';
+                 if (strchr(gdb_completer_quote_characters, copy[p-*argptr-1]) != NULL)
+                   copy[p - *argptr -1] = '\0';
                }
 
              /* no line number may be specified */
@@ -1800,9 +1979,12 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
                  if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)
                    {
                      /* Arg is the name of a function */
-                     pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) + FUNCTION_START_OFFSET;
+                     pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
                      if (funfirstline)
-                       SKIP_PROLOGUE (pc);
+                       {
+                         pc += FUNCTION_START_OFFSET;
+                         SKIP_PROLOGUE (pc);
+                       }
                      values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line));
                      values.nelts = 1;
                      values.sals[0] = find_pc_line (pc, 0);
@@ -1881,12 +2063,12 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
 
   /* Check whether arg is all digits (and sign) */
 
-  p = *argptr;
-  if (*p == '-' || *p == '+') p++;
-  while (*p >= '0' && *p <= '9')
-    p++;
+  q = *argptr;
+  if (*q == '-' || *q == '+') q++;
+  while (*q >= '0' && *q <= '9')
+    q++;
 
-  if (p != *argptr && (*p == 0 || *p == ' ' || *p == '\t' || *p == ','))
+  if (q != *argptr && (*q == 0 || *q == ' ' || *q == '\t' || *q == ','))
     {
       /* We found a token consisting of all digits -- at least one digit.  */
       enum sign {none, plus, minus} sign = none;
@@ -1914,13 +2096,13 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
       switch (sign)
        {
        case plus:
-         if (p == *argptr)
+         if (q == *argptr)
            val.line = 5;
          if (s == 0)
            val.line = default_line + val.line;
          break;
        case minus:
-         if (p == *argptr)
+         if (q == *argptr)
            val.line = 15;
          if (s == 0)
            val.line = default_line - val.line;
@@ -1931,8 +2113,8 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
          break;        /* No need to adjust val.line.  */
        }
 
-      while (*p == ' ' || *p == '\t') p++;
-      *argptr = p;
+      while (*q == ' ' || *q == '\t') q++;
+      *argptr = q;
       if (s == 0)
        s = default_symtab;
       val.symtab = s;
@@ -1948,16 +2130,27 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
   /* Arg token is not digits => try it as a variable name
      Find the next token (everything up to end or next whitespace).  */
 
-  p = skip_quoted (*argptr);
-  if (is_quoted && p[-1] != '\'')
-    error ("Unmatched single quote.");
+  if (is_quoted)
+    {
+      p = skip_quoted (*argptr);
+      if (p[-1] != '\'')
+        error ("Unmatched single quote.");
+    }
+  else if (has_parens)
+    {
+      p = pp+1;
+    }
+  else 
+    {
+      p = skip_quoted(*argptr);
+    }
+
   copy = (char *) alloca (p - *argptr + 1);
   memcpy (copy, *argptr, p - *argptr);
   copy[p - *argptr] = '\0';
   if ((copy[0] == copy [p - *argptr - 1])
       && strchr (gdb_completer_quote_characters, copy[0]) != NULL)
     {
-      char *temp;
       copy [p - *argptr - 1] = '\0';
       copy++;
     }
@@ -1977,9 +2170,12 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
       if (SYMBOL_CLASS (sym) == LOC_BLOCK)
        {
          /* Arg is the name of a function */
-         pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) + FUNCTION_START_OFFSET;
+         pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
          if (funfirstline)
-           SKIP_PROLOGUE (pc);
+           {
+             pc += FUNCTION_START_OFFSET;
+             SKIP_PROLOGUE (pc);
+           }
          val = find_pc_line (pc, 0);
 #ifdef PROLOGUE_FIRSTLINE_OVERLAP
          /* Convex: no need to suppress code on first line, if any */
@@ -2001,15 +2197,13 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
          values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line));
          values.sals[0] = val;
          values.nelts = 1;
-         
-         /* I think this is always the same as the line that
-            we calculate above, but the general principle is
-            "trust the symbols more than stuff like
-            SKIP_PROLOGUE".  */
-         if (SYMBOL_LINE (sym) != 0)
-           values.sals[0].line = SYMBOL_LINE (sym);
-
-         /* We might need a canonical line spec if it is a static function.  */
+
+         /* Don't use the SYMBOL_LINE; if used at all it points to
+            the line containing the parameters or thereabouts, not
+            the first line of code.  */
+
+         /* We might need a canonical line spec if it is a static
+            function.  */
          if (s == 0)
            {
              struct blockvector *bv = BLOCKVECTOR (sym_symtab);
@@ -2043,9 +2237,12 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
     {
       val.symtab = 0;
       val.line = 0;
-      val.pc = SYMBOL_VALUE_ADDRESS (msymbol) + FUNCTION_START_OFFSET;
+      val.pc = SYMBOL_VALUE_ADDRESS (msymbol);
       if (funfirstline)
-       SKIP_PROLOGUE (val.pc);
+       {
+         val.pc += FUNCTION_START_OFFSET;
+         SKIP_PROLOGUE (val.pc);
+       }
       values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line));
       values.sals[0] = val;
       values.nelts = 1;
@@ -2110,23 +2307,25 @@ decode_line_2 (sym_arr, nelts, funfirstline, canonical)
     }
 
   i = 0;
-  printf("[0] cancel\n[1] all\n");
+  printf_unfiltered("[0] cancel\n[1] all\n");
   while (i < nelts)
     {
       if (sym_arr[i] && SYMBOL_CLASS (sym_arr[i]) == LOC_BLOCK)
        {
          /* Arg is the name of a function */
-         pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym_arr[i])) 
-              + FUNCTION_START_OFFSET;
+         pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym_arr[i]));
          if (funfirstline)
-           SKIP_PROLOGUE (pc);
+           {
+             pc += FUNCTION_START_OFFSET;
+             SKIP_PROLOGUE (pc);
+           }
          values.sals[i] = find_pc_line (pc, 0);
          values.sals[i].pc = (values.sals[i].end && values.sals[i].pc != pc) ?
                               values.sals[i].end                      :  pc;
-         printf("[%d] %s at %s:%d\n", (i+2), SYMBOL_SOURCE_NAME (sym_arr[i]),
+         printf_unfiltered("[%d] %s at %s:%d\n", (i+2), SYMBOL_SOURCE_NAME (sym_arr[i]),
                 values.sals[i].symtab->filename, values.sals[i].line);
        }
-      else printf ("?HERE\n");
+      else printf_unfiltered ("?HERE\n");
       i++;
     }
   
@@ -2134,8 +2333,8 @@ decode_line_2 (sym_arr, nelts, funfirstline, canonical)
     {
       prompt = ">";
     }
-  printf("%s ",prompt);
-  fflush(stdout);
+  printf_unfiltered("%s ",prompt);
+  gdb_flush(gdb_stdout);
 
   args = command_line_input ((char *) NULL, 0);
   
@@ -2178,7 +2377,7 @@ decode_line_2 (sym_arr, nelts, funfirstline, canonical)
 
       if (num > nelts + 2)
        {
-         printf ("No choice number %d.\n", num);
+         printf_unfiltered ("No choice number %d.\n", num);
        }
       else
        {
@@ -2196,7 +2395,7 @@ decode_line_2 (sym_arr, nelts, funfirstline, canonical)
            }
          else
            {
-             printf ("duplicate request for %d ignored.\n", num);
+             printf_unfiltered ("duplicate request for %d ignored.\n", num);
            }
        }
 
@@ -2265,7 +2464,7 @@ output_source_filename (name, first)
     }
 
   wrap_here ("");
-  fputs_filtered (name, stdout);
+  fputs_filtered (name, gdb_stdout);
 }  
 
 static void
@@ -2514,9 +2713,9 @@ list_symbols (regexp, class, bpt)
                      }
                    else if (!found_in_file)
                      {
-                       fputs_filtered ("\nFile ", stdout);
-                       fputs_filtered (s->filename, stdout);
-                       fputs_filtered (":\n", stdout);
+                       fputs_filtered ("\nFile ", gdb_stdout);
+                       fputs_filtered (s->filename, gdb_stdout);
+                       fputs_filtered (":\n", gdb_stdout);
                      }
                    found_in_file = 1;
                    
@@ -2526,7 +2725,7 @@ list_symbols (regexp, class, bpt)
                    /* Typedef that is not a C++ class */
                    if (class == 2
                        && SYMBOL_NAMESPACE (sym) != STRUCT_NAMESPACE)
-                     c_typedef_print (SYMBOL_TYPE(sym), sym, stdout);
+                     c_typedef_print (SYMBOL_TYPE(sym), sym, gdb_stdout);
                    /* variable, func, or typedef-that-is-c++-class */
                    else if (class < 2 || 
                             (class == 2 && 
@@ -2535,7 +2734,7 @@ list_symbols (regexp, class, bpt)
                        type_print (SYMBOL_TYPE (sym),
                                    (SYMBOL_CLASS (sym) == LOC_TYPEDEF
                                     ? "" : SYMBOL_SOURCE_NAME (sym)),
-                                   stdout, 0);
+                                   gdb_stdout, 0);
                        
                        printf_filtered (";\n");
                      }
@@ -2544,12 +2743,12 @@ list_symbols (regexp, class, bpt)
 # if 0  /* FIXME, why is this zapped out? */
                        char buf[1024];
                        c_type_print_base (TYPE_FN_FIELD_TYPE(t, i),
-                                          stdout, 0, 0); 
+                                          gdb_stdout, 0, 0); 
                        c_type_print_varspec_prefix (TYPE_FN_FIELD_TYPE(t, i),
-                                                    stdout, 0); 
+                                                    gdb_stdout, 0); 
                        sprintf (buf, " %s::", type_name_no_tag (t));
                        cp_type_print_method_args (TYPE_FN_FIELD_ARGS (t, i),
-                                                  buf, name, stdout);
+                                                  buf, name, gdb_stdout);
 # endif
                      }
                  }
@@ -2585,8 +2784,8 @@ list_symbols (regexp, class, bpt)
                              printf_filtered ("\nNon-debugging symbols:\n");
                              found_in_file = 1;
                            }
-                         printf_filtered ("    %08x  %s\n",
-                                          SYMBOL_VALUE_ADDRESS (msymbol),
+                         printf_filtered ("    %08lx  %s\n",
+                                          (unsigned long) SYMBOL_VALUE_ADDRESS (msymbol),
                                           SYMBOL_SOURCE_NAME (msymbol));
                        }
                    }
@@ -2662,11 +2861,15 @@ static char **return_val;
 
 #define COMPLETION_LIST_ADD_SYMBOL(symbol, sym_text, len, text, word) \
   do { \
-    completion_list_add_name (SYMBOL_NAME (symbol), (sym_text), (len), \
-                             (text), (word)); \
     if (SYMBOL_DEMANGLED_NAME (symbol) != NULL) \
+      /* Put only the mangled name on the list.  */ \
+      /* Advantage:  "b foo<TAB>" completes to "b foo(int, int)" */ \
+      /* Disadvantage:  "b foo__i<TAB>" doesn't complete.  */ \
       completion_list_add_name \
        (SYMBOL_DEMANGLED_NAME (symbol), (sym_text), (len), (text), (word)); \
+    else \
+      completion_list_add_name \
+       (SYMBOL_NAME (symbol), (sym_text), (len), (text), (word)); \
   } while (0)
 
 /*  Test to see if the symbol specified by SYMNAME (which is already
@@ -2767,7 +2970,7 @@ make_symbol_completion_list (text, word)
   {
     char *p;
     char quote_found;
-    char *quote_pos;
+    char *quote_pos = NULL;
 
     /* First see if this is a quoted string.  */
     quote_found = '\0';
This page took 0.034922 seconds and 4 git commands to generate.