#include "command.h"
#include "symfile.h"
#include "objfiles.h"
+#include "source.h"
#include "demangle.h"
#include "value.h"
#include "completer.h"
-
-/* Prototype for one function in parser-defs.h,
- instead of including that entire file. */
-
-extern char *find_template_name_end (char *);
+#include "cp-abi.h"
+#include "parser-defs.h"
/* We share this one with symtab.c, but it is not exported widely. */
/* Prototypes for local functions */
-static void cplusplus_hint (char *name);
+static void cplusplus_error (const char *name, const char *fmt, ...) ATTR_FORMAT (printf, 2, 3);
static int total_number_of_methods (struct type *type);
/* Helper functions. */
-/* While the C++ support is still in flux, issue a possibly helpful hint on
- using the new command completion feature on single quoted demangled C++
- symbols. Remove when loose ends are cleaned up. FIXME -fnf */
+/* Issue a helpful hint on using the command completion feature on
+ single quoted demangled C++ symbols as part of the completion
+ error. */
static void
-cplusplus_hint (char *name)
+cplusplus_error (const char *name, const char *fmt, ...)
{
+ struct ui_file *tmp_stream;
+ tmp_stream = mem_fileopen ();
+ make_cleanup_ui_file_delete (tmp_stream);
+
+ {
+ va_list args;
+ va_start (args, fmt);
+ vfprintf_unfiltered (tmp_stream, fmt, args);
+ va_end (args);
+ }
+
while (*name == '\'')
name++;
- printf_filtered ("Hint: try '%s<TAB> or '%s<ESC-?>\n", name, name);
- printf_filtered ("(Note leading single quote.)\n");
+ fprintf_unfiltered (tmp_stream,
+ ("Hint: try '%s<TAB> or '%s<ESC-?>\n"
+ "(Note leading single quote.)"),
+ name, name);
+ error_stream (tmp_stream);
}
/* Return the number of methods described for TYPE, including the
(struct symtab **) NULL)))
{
int method_counter;
+ int name_len = strlen (name);
CHECK_TYPEDEF (t);
phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
/* Destructor is handled by caller, dont add it to the list */
- if (DESTRUCTOR_PREFIX_P (phys_name))
+ if (is_destructor_name (phys_name) != 0)
continue;
sym_arr[i1] = lookup_symbol (phys_name,
*/
}
}
+ else if (strncmp (class_name, name, name_len) == 0
+ && (class_name[name_len] == '\0'
+ || class_name[name_len] == '<'))
+ {
+ /* For GCC 3.x and stabs, constructors and destructors have names
+ like __base_ctor and __complete_dtor. Check the physname for now
+ if we're looking for a constructor. */
+ for (field_counter
+ = TYPE_FN_FIELDLIST_LENGTH (t, method_counter) - 1;
+ field_counter >= 0;
+ --field_counter)
+ {
+ struct fn_field *f;
+ char *phys_name;
+
+ f = TYPE_FN_FIELDLIST1 (t, method_counter);
+
+ /* GCC 3.x will never produce stabs stub methods, so we don't need
+ to handle this case. */
+ if (TYPE_FN_FIELD_STUB (f, field_counter))
+ continue;
+ phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
+ if (! is_constructor_name (phys_name))
+ continue;
+
+ /* If this method is actually defined, include it in the
+ list. */
+ sym_arr[i1] = lookup_symbol (phys_name,
+ NULL, VAR_NAMESPACE,
+ (int *) NULL,
+ (struct symtab **) NULL);
+ if (sym_arr[i1])
+ i1++;
+ }
+ }
}
}
/* Find an instance of the character C in the string S that is outside
of all parenthesis pairs, single-quoted strings, and double-quoted
- strings. */
+ strings. Also, ignore the char within a template name, like a ','
+ within foo<int, int>. */
+
static char *
find_toplevel_char (char *s, char c)
{
return scan;
else if (*scan == '"' || *scan == '\'')
quoted = *scan;
- else if (*scan == '(')
+ else if (*scan == '(' || *scan == '<')
depth++;
- else if (*scan == ')' && depth > 0)
+ else if ((*scan == ')' || *scan == '>') && depth > 0)
depth--;
}
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);
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 */
opname = cplus_mangle_opname (tmp, DMGL_ANSI);
if (opname == NULL)
{
- error_begin ();
- printf_filtered ("no mangling for \"%s\"\n", tmp);
- cplusplus_hint (saved_arg);
- return_to_top_level (RETURN_ERROR);
+ cplusplus_error (saved_arg, "no mangling for \"%s\"\n", tmp);
}
copy = (char*) alloca (3 + strlen(opname));
sprintf (copy, "__%s", opname);
{
char *tmp;
- if (OPNAME_PREFIX_P (copy))
+ if (is_operator_name (copy))
{
tmp = (char *) alloca (strlen (copy + 3) + 9);
strcpy (tmp, "operator ");
}
else
tmp = copy;
- error_begin ();
if (tmp[0] == '~')
- printf_filtered
- ("the class `%s' does not have destructor defined\n",
- SYMBOL_SOURCE_NAME (sym_class));
+ cplusplus_error (saved_arg,
+ "the class `%s' does not have destructor defined\n",
+ SYMBOL_SOURCE_NAME (sym_class));
else
- printf_filtered
- ("the class %s does not have any method named %s\n",
- SYMBOL_SOURCE_NAME (sym_class), tmp);
- cplusplus_hint (saved_arg);
- return_to_top_level (RETURN_ERROR);
+ cplusplus_error (saved_arg,
+ "the class %s does not have any method named %s\n",
+ SYMBOL_SOURCE_NAME (sym_class), tmp);
}
}
goto symbol_found;
/* Couldn't find any interpretation as classes/namespaces, so give up */
- error_begin ();
/* The quotes are important if copy is empty. */
- printf_filtered
- ("Can't find member of namespace, class, struct, or union named \"%s\"\n", copy);
- cplusplus_hint (saved_arg);
- return_to_top_level (RETURN_ERROR);
+ cplusplus_error (saved_arg,
+ "Can't find member of namespace, class, struct, or union named \"%s\"\n",
+ copy);
}
/* end of C++ */
if ((*p == '"') && is_quote_enclosed)
--p;
copy = (char *) alloca (p - *argptr + 1);
- if ((**argptr == '"') && is_quote_enclosed)
- {
- memcpy (copy, *argptr + 1, p - *argptr - 1);
- /* It may have the ending quote right after the file name */
- if (copy[p - *argptr - 2] == '"')
- copy[p - *argptr - 2] = 0;
- else
- copy[p - *argptr - 1] = 0;
- }
+ memcpy (copy, *argptr, p - *argptr);
+ /* It may have the ending quote right after the file name */
+ if (is_quote_enclosed && copy[p - *argptr - 1] == '"')
+ copy[p - *argptr - 1] = 0;
else
- {
- memcpy (copy, *argptr, p - *argptr);
- copy[p - *argptr] = 0;
- }
+ copy[p - *argptr] = 0;
/* Find that file's data. */
s = lookup_symtab (copy);
/* 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 == '+')
if (*copy == '$')
{
- value_ptr valx;
+ struct value *valx;
int index = 0;
int need_canonical = 0;
goto symbol_found;
/* If symbol was not found, look in minimal symbol tables */
- msymbol = lookup_minimal_symbol (copy, 0, 0);
+ msymbol = lookup_minimal_symbol (copy, NULL, NULL);
/* Min symbol was found --> jump to minsym processing. */
if (msymbol)
goto minimal_symbol_found;
sym = lookup_symbol (copy,
(s ? BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK)
- : get_selected_block ()),
+ : get_selected_block (0)),
VAR_NAMESPACE, 0, &sym_symtab);
symbol_found: /* We also jump here from inside the C++ class/namespace
{
struct blockvector *bv = BLOCKVECTOR (sym_symtab);
struct block *b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- if (lookup_block_symbol (b, copy, VAR_NAMESPACE) != NULL)
+ if (lookup_block_symbol (b, copy, NULL, VAR_NAMESPACE) != NULL)
build_canonical_line_spec (values.sals, copy, canonical);
}
return values;