2002-11-08 David Carlton <carlton@math.stanford.edu>
[deliverable/binutils-gdb.git] / gdb / linespec.c
index 8e51021fc44a071d58eb75973d93fb0c4481dae5..e496c71132b56f565cf30b9a57d95e9b53c17a63 100644 (file)
 #include "command.h"
 #include "symfile.h"
 #include "objfiles.h"
+#include "source.h"
 #include "demangle.h"
 #include "value.h"
 #include "completer.h"
 #include "cp-abi.h"
-
-/* Prototype for one function in parser-defs.h,
-   instead of including that entire file. */
-
-extern char *find_template_name_end (char *);
+#include "parser-defs.h"
 
 /* We share this one with symtab.c, but it is not exported widely. */
 
@@ -56,6 +53,18 @@ static char *find_toplevel_char (char *s, char c);
 static struct symtabs_and_lines decode_line_2 (struct symbol *[],
                                               int, int, char ***);
 
+static struct
+symtabs_and_lines symbol_found (int funfirstline,
+                               char ***canonical,
+                               char *copy,
+                               struct symbol *sym,
+                               struct symtab *s,
+                               struct symtab *sym_symtab);
+
+static struct
+symtabs_and_lines minsym_found (int funfirstline,
+                               struct minimal_symbol *msymbol);
+
 /* Helper functions. */
 
 /* Issue a helpful hint on using the command completion feature on
@@ -370,8 +379,8 @@ decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline,
   printf_unfiltered ("[0] cancel\n[1] all\n");
   while (i < nelts)
     {
-      INIT_SAL (&return_values.sals[i]);       /* initialize to zeroes */
-      INIT_SAL (&values.sals[i]);
+      init_sal (&return_values.sals[i]);       /* initialize to zeroes */
+      init_sal (&values.sals[i]);
       if (sym_arr[i] && SYMBOL_CLASS (sym_arr[i]) == LOC_BLOCK)
        {
          values.sals[i] = find_function_start_sal (sym_arr[i], funfirstline);
@@ -539,14 +548,20 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
   char *saved_arg = *argptr;
   extern char *gdb_completer_quote_characters;
 
-  INIT_SAL (&val);             /* initialize to zeroes */
+  init_sal (&val);             /* initialize to zeroes */
 
   /* Defaults have defaults.  */
 
   if (default_symtab == 0)
     {
-      default_symtab = current_source_symtab;
-      default_line = current_source_line;
+      /* Use whatever we have for the default source line.  We don't use
+         get_current_or_default_symtab_and_line as it can recurse and call
+        us back! */
+      struct symtab_and_line cursal = 
+                       get_current_source_symtab_and_line ();
+      
+      default_symtab = cursal.symtab;
+      default_line = cursal.line;
     }
 
   /* See if arg is *PC */
@@ -907,16 +922,9 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
          /* Look up entire name */
          sym = lookup_symbol (copy, 0, VAR_NAMESPACE, 0, &sym_symtab);
          s = (struct symtab *) 0;
-         /* Prepare to jump: restore the " if (condition)" so outer layers see it */
-         /* Symbol was found --> jump to normal symbol processing.
-            Code following "symbol_found" expects "copy" to have the
-            symbol name, "sym" to have the symbol pointer, "s" to be
-            a specified file's symtab, and sym_symtab to be the symbol's
-            symtab. */
-         /* By jumping there we avoid falling through the FILE:LINE and
-            FILE:FUNC processing stuff below */
          if (sym)
-           goto symbol_found;
+           return symbol_found (funfirstline, canonical, copy, sym,
+                                NULL, sym_symtab);
 
          /* Couldn't find any interpretation as classes/namespaces, so give up */
          /* The quotes are important if copy is empty.  */
@@ -982,12 +990,9 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
       sym = lookup_symbol (copy, 0, VAR_NAMESPACE, 0, &sym_symtab);
       if (sym)
        {
-         /* Yes, we have a symbol; jump to symbol processing */
-         /* Code after symbol_found expects S, SYM_SYMTAB, SYM, 
-            and COPY to be set correctly */
          *argptr = (*p == '\'') ? p + 1 : p;
-         s = (struct symtab *) 0;
-         goto symbol_found;
+         return symbol_found (funfirstline, canonical, copy, sym,
+                              NULL, sym_symtab);
        }
       /* Otherwise fall out from here and go to file/line spec
          processing, etc. */
@@ -1020,13 +1025,19 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
       /* This is where we need to make sure that we have good defaults.
          We must guarantee that this section of code is never executed
          when we are called with just a function name, since
-         select_source_symtab calls us with such an argument  */
+        set_default_source_symtab_and_line uses
+         select_source_symtab that calls us with such an argument  */
 
       if (s == 0 && default_symtab == 0)
        {
-         select_source_symtab (0);
-         default_symtab = current_source_symtab;
-         default_line = current_source_line;
+          struct symtab_and_line cursal;
+
+         /* Make sure we have at least a default source file. */
+         set_default_source_symtab_and_line ();
+          cursal = get_current_source_symtab_and_line ();
+      
+          default_symtab = cursal.symtab;
+          default_line = cursal.line;
        }
 
       if (**argptr == '+')
@@ -1142,19 +1153,16 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
          sym = lookup_symbol (copy, 0, VAR_NAMESPACE, 0, &sym_symtab);
          s = (struct symtab *) 0;
          need_canonical = 1;
-         /* Symbol was found --> jump to normal symbol processing.
-            Code following "symbol_found" expects "copy" to have the
-            symbol name, "sym" to have the symbol pointer, "s" to be
-            a specified file's symtab, and sym_symtab to be the symbol's
-            symtab. */
+         /* Symbol was found --> jump to normal symbol processing.  */
          if (sym)
-           goto symbol_found;
+           return symbol_found (funfirstline, canonical, copy, sym,
+                                NULL, sym_symtab);
 
          /* If symbol was not found, look in minimal symbol tables */
          msymbol = lookup_minimal_symbol (copy, NULL, NULL);
          /* Min symbol was found --> jump to minsym processing. */
          if (msymbol)
-           goto minimal_symbol_found;
+           return minsym_found (funfirstline, msymbol);
 
          /* Not a user variable or function -- must be convenience variable */
          need_canonical = (s == 0) ? 1 : 0;
@@ -1187,84 +1195,104 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
                        : get_selected_block (0)),
                       VAR_NAMESPACE, 0, &sym_symtab);
 
-symbol_found:                  /* We also jump here from inside the C++ class/namespace 
-                                  code on finding a symbol of the form "A::B::C" */
-
   if (sym != NULL)
-    {
-      if (SYMBOL_CLASS (sym) == LOC_BLOCK)
-       {
-         /* Arg is the name of a function */
-         values.sals = (struct symtab_and_line *)
-           xmalloc (sizeof (struct symtab_and_line));
-         values.sals[0] = find_function_start_sal (sym, funfirstline);
-         values.nelts = 1;
+    return symbol_found (funfirstline, canonical, copy, sym, s, sym_symtab);
 
-         /* 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.  */
+  msymbol = lookup_minimal_symbol (copy, NULL, NULL);
 
-         /* We might need a canonical line spec if it is a static
-            function.  */
-         if (s == 0)
-           {
-             struct blockvector *bv = BLOCKVECTOR (sym_symtab);
-             struct block *b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-             if (lookup_block_symbol (b, copy, NULL, VAR_NAMESPACE) != NULL)
-               build_canonical_line_spec (values.sals, copy, canonical);
-           }
-         return values;
-       }
-      else
-       {
-         if (funfirstline)
-           error ("\"%s\" is not a function", copy);
-         else if (SYMBOL_LINE (sym) != 0)
-           {
-             /* We know its line number.  */
-             values.sals = (struct symtab_and_line *)
-               xmalloc (sizeof (struct symtab_and_line));
-             values.nelts = 1;
-             memset (&values.sals[0], 0, sizeof (values.sals[0]));
-             values.sals[0].symtab = sym_symtab;
-             values.sals[0].line = SYMBOL_LINE (sym);
-             return values;
-           }
-         else
-           /* This can happen if it is compiled with a compiler which doesn't
-              put out line numbers for variables.  */
-           /* FIXME: Shouldn't we just set .line and .symtab to zero
-              and return?  For example, "info line foo" could print
-              the address.  */
-           error ("Line number not known for symbol \"%s\"", copy);
-       }
-    }
+  if (msymbol != NULL)
+    return minsym_found (funfirstline, msymbol);
 
-  msymbol = lookup_minimal_symbol (copy, NULL, NULL);
+  if (!have_full_symbols () &&
+      !have_partial_symbols () && !have_minimal_symbols ())
+    error ("No symbol table is loaded.  Use the \"file\" command.");
 
-minimal_symbol_found:          /* We also jump here from the case for variables
-                                  that begin with '$' */
+  error ("Function \"%s\" not defined.", copy);
+  return values;               /* for lint */
+}
 
-  if (msymbol != NULL)
+
+\f
+
+/* Now come some functions that are called from multiple places within
+   decode_line_1.  */
+
+/* We've found a symbol SYM to associate with our linespec; build a
+   corresponding struct symtabs_and_lines.  */
+
+static struct symtabs_and_lines
+symbol_found (int funfirstline, char ***canonical, char *copy,
+             struct symbol *sym, struct symtab *s,
+             struct symtab *sym_symtab)
+{
+  struct symtabs_and_lines values;
+  
+  if (SYMBOL_CLASS (sym) == LOC_BLOCK)
     {
+      /* Arg is the name of a function */
       values.sals = (struct symtab_and_line *)
        xmalloc (sizeof (struct symtab_and_line));
-      values.sals[0] = find_pc_sect_line (SYMBOL_VALUE_ADDRESS (msymbol),
-                                         (struct sec *) 0, 0);
-      values.sals[0].section = SYMBOL_BFD_SECTION (msymbol);
-      if (funfirstline)
+      values.sals[0] = find_function_start_sal (sym, funfirstline);
+      values.nelts = 1;
+
+      /* 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)
        {
-         values.sals[0].pc += FUNCTION_START_OFFSET;
-         values.sals[0].pc = SKIP_PROLOGUE (values.sals[0].pc);
+         struct blockvector *bv = BLOCKVECTOR (sym_symtab);
+         struct block *b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+         if (lookup_block_symbol (b, copy, NULL, VAR_NAMESPACE) != NULL)
+           build_canonical_line_spec (values.sals, copy, canonical);
        }
-      values.nelts = 1;
       return values;
     }
+  else
+    {
+      if (funfirstline)
+       error ("\"%s\" is not a function", copy);
+      else if (SYMBOL_LINE (sym) != 0)
+       {
+         /* We know its line number.  */
+         values.sals = (struct symtab_and_line *)
+           xmalloc (sizeof (struct symtab_and_line));
+         values.nelts = 1;
+         memset (&values.sals[0], 0, sizeof (values.sals[0]));
+         values.sals[0].symtab = sym_symtab;
+         values.sals[0].line = SYMBOL_LINE (sym);
+         return values;
+       }
+      else
+       /* This can happen if it is compiled with a compiler which doesn't
+          put out line numbers for variables.  */
+       /* FIXME: Shouldn't we just set .line and .symtab to zero
+          and return?  For example, "info line foo" could print
+          the address.  */
+       error ("Line number not known for symbol \"%s\"", copy);
+    }
+}
 
-  if (!have_full_symbols () &&
-      !have_partial_symbols () && !have_minimal_symbols ())
-    error ("No symbol table is loaded.  Use the \"file\" command.");
+/* We've found a minimal symbol MSYMBOL to associate with our
+   linespec; build a corresponding struct symtabs_and_lines.  */
 
-  error ("Function \"%s\" not defined.", copy);
-  return values;               /* for lint */
+static struct symtabs_and_lines
+minsym_found (int funfirstline, struct minimal_symbol *msymbol)
+{
+  struct symtabs_and_lines values;
+
+  values.sals = (struct symtab_and_line *)
+    xmalloc (sizeof (struct symtab_and_line));
+  values.sals[0] = find_pc_sect_line (SYMBOL_VALUE_ADDRESS (msymbol),
+                                     (struct sec *) 0, 0);
+  values.sals[0].section = SYMBOL_BFD_SECTION (msymbol);
+  if (funfirstline)
+    {
+      values.sals[0].pc += FUNCTION_START_OFFSET;
+      values.sals[0].pc = SKIP_PROLOGUE (values.sals[0].pc);
+    }
+  values.nelts = 1;
+  return values;
 }
This page took 0.032164 seconds and 4 git commands to generate.