This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [patch 3/3 optional] Template Lookup
- From: sami wagiaalla <swagiaal at redhat dot com>
- To: gdb-patches at sourceware dot org
- Date: Mon, 30 Aug 2010 10:59:12 -0400
- Subject: Re: [patch 3/3 optional] Template Lookup
- References: <4C446F53.7000209@redhat.com> <m3hbira7oy.fsf@fleche.redhat.com>
Revised patch attached.
Template Lookup 3: Template meta var learns about its instances.
2010-08-30 Sami Wagiaalla <swagiaal@redhat.com>
* symtab.h (symbol_add_template_instance): New function prototype.
(symbol_get_template_instances): New function prototype.
Created struct symbol_list_element.
Created struct template_symbol.
(instances): Add an instance of symbol_list_element to
general_symbol_info
* symtab.c (symbol_add_template_instance): New function.
(symbol_get_template_instances): New function.
* findvar.c (read_var_value): Print list of candidates when
attempting to evaluate a LOC_TEMPLATE.
* dwarf2read.c (add_template_variable): Find template variable and
add instance reference to it.
2010-08-30 Sami Wagiaalla <swagiaal@redhat.com>
* gdb.cp/temp-op.exp: Test printing of template instances.
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index bf57650..cbee89d 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -8647,7 +8647,7 @@ add_template_variable (struct symbol *symbol, struct pending **listhead,
struct objfile *objfile)
{
const struct pending *iterator = *listhead;
- struct symbol *template_sym;
+ struct template_symbol *template_sym = NULL;
struct symbol *iterator_sym;
struct type *type;
char *name = SYMBOL_NATURAL_NAME (symbol);
@@ -8677,7 +8677,7 @@ add_template_variable (struct symbol *symbol, struct pending **listhead,
/* Has a template symbol for this symbol been added already ? */
for (iterator = *(listhead);
- iterator != NULL;
+ iterator != NULL && template_sym == NULL;
iterator = iterator->next)
{
for (i = iterator->nsyms - 1; i >= 0; --i)
@@ -8687,28 +8687,38 @@ add_template_variable (struct symbol *symbol, struct pending **listhead,
if (TYPE_CODE (SYMBOL_TYPE (iterator_sym)) == TYPE_CODE_TEMPLATE
&& strcmp (SYMBOL_SEARCH_NAME (iterator_sym), search_name) == 0)
{
- do_cleanups (all_cleanups);
- return;
+ template_sym = (struct template_symbol *) iterator_sym;
+ break;
}
}
}
- /* Add a new template symbol. */
- template_sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
- sizeof (struct symbol));
- OBJSTAT (objfile, n_syms++);
- memset (template_sym, 0, sizeof (struct symbol));
+ if (template_sym == NULL)
+ {
+ /* Add a new template symbol. */
+ template_sym = (struct template_symbol *)
+ obstack_alloc (&objfile->objfile_obstack,
+ sizeof (struct template_symbol));
- SYMBOL_SET_NAMES (template_sym, search_name, strlen (search_name), 0, objfile);
- type = alloc_type (objfile);
- TYPE_CODE (type) = TYPE_CODE_TEMPLATE;
- SYMBOL_TYPE (template_sym) = type;
+ OBJSTAT (objfile, n_syms++);
+ memset (&template_sym->sym, 0, sizeof (struct symbol));
+
+ SYMBOL_SET_NAMES (&template_sym->sym,
+ search_name,
+ strlen (search_name),
+ 0, objfile);
- SYMBOL_DOMAIN (template_sym) = VAR_DOMAIN;
- SYMBOL_CLASS (template_sym) = LOC_TEMPLATE;
+ type = alloc_type (objfile);
+ TYPE_CODE (type) = TYPE_CODE_TEMPLATE;
+ SYMBOL_TYPE (&template_sym->sym) = type;
- add_symbol_to_list (template_sym, listhead);
+ SYMBOL_DOMAIN (&template_sym->sym) = VAR_DOMAIN;
+ SYMBOL_CLASS (&template_sym->sym) = LOC_TEMPLATE;
+
+ add_symbol_to_list (&template_sym->sym, listhead);
+ }
+ symbol_add_template_instance (template_sym, symbol, objfile);
do_cleanups (all_cleanups);
}
diff --git a/gdb/findvar.c b/gdb/findvar.c
index f4749b7..1d2f2a8 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -35,6 +35,7 @@
#include "user-regs.h"
#include "block.h"
#include "objfiles.h"
+#include "exceptions.h"
/* Basic byte-swapping routines. All 'extract' functions return a
host-format integer from a target-format integer at ADDR which is
@@ -568,9 +569,20 @@ read_var_value (struct symbol *var, struct frame_info *frame)
return v;
case LOC_TEMPLATE:
- error (_("Symbol represents a template and cannot be evaluated."));
- break;
+ {
+ const struct symbol_list_element *instance =
+ symbol_get_template_instances (var);
+
+ printf_filtered ("Symbol represents a template and cannot be evaluated.\n");
+ printf_filtered ("Did you mean:\n");
+ while (instance != NULL)
+ {
+ printf_filtered (" %s\n", SYMBOL_NATURAL_NAME (instance->sym));
+ instance = instance->next;
+ }
+ throw_error (NOT_FOUND_ERROR, " ");
+ }
default:
error (_("Cannot look up value of a botched symbol."));
break;
diff --git a/gdb/symtab.c b/gdb/symtab.c
index d0abc2d..d2dc528 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -343,6 +343,28 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id)
/* Initialize the cplus_specific structure. 'cplus_specific' should
only be allocated for use with cplus symbols. */
+void
+symbol_add_template_instance (struct template_symbol *template_sym,
+ const struct symbol *instance,
+ struct objfile *objfile)
+{
+ struct symbol_list_element *new_instance =
+ OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ struct symbol_list_element);
+
+ new_instance->sym = instance;
+ new_instance->next = template_sym->instances;
+ template_sym->instances = new_instance;
+}
+
+/* Return the list of known instances of this template symbol. */
+
+const struct symbol_list_element *
+symbol_get_template_instances (const struct symbol *sym)
+{
+ return ((struct template_symbol *) sym)->instances;
+}
+
static void
symbol_init_cplus_specific (struct general_symbol_info *gsymbol,
struct objfile *objfile)
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 46d3584..c98657c 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -75,6 +75,15 @@ struct program_space;
--chastain 2003-08-21 */
+/* A likend list of symbols used to keep references to
+ instances of a template. */
+
+struct symbol_list_element
+{
+ struct symbol_list_element *next;
+ const struct symbol *sym;
+};
+
/* Struct for storing C++ specific information. Allocated when needed. */
struct cplus_specific
@@ -649,6 +658,21 @@ struct symbol
struct symbol *hash_next;
};
+/* A "subclass" of symbol object for representing templates. */
+
+struct template_symbol
+{
+ struct symbol sym;
+ struct symbol_list_element *instances;
+};
+
+extern void
+symbol_add_template_instance (struct template_symbol *template_sym,
+ const struct symbol *instance,
+ struct objfile *objfile);
+
+extern const struct symbol_list_element *
+symbol_get_template_instances (const struct symbol *sym);
#define SYMBOL_DOMAIN(symbol) (symbol)->domain
#define SYMBOL_CLASS(symbol) (symbol)->aclass
diff --git a/gdb/testsuite/gdb.cp/temp-op.exp b/gdb/testsuite/gdb.cp/temp-op.exp
index 21e644f..7352e14 100644
--- a/gdb/testsuite/gdb.cp/temp-op.exp
+++ b/gdb/testsuite/gdb.cp/temp-op.exp
@@ -63,5 +63,5 @@ gdb_test "p bc == 'a'" "= 19"
# Test that printing the a template name without
# template parameters does not return an arbitrary match
-gdb_test "print foo" "Symbol represents a template and cannot be evaluated."
-gdb_test "ptype B" "type = Template Symbol"
+gdb_test "print foo" "Symbol represents a template and cannot be evaluated.*foo<A>\\(A, char\\).*"
+gdb_test "ptype B" "Symbol represents a template and cannot be evaluated.*B<char>.*B<int>.*"