This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch 3/3 optional] Template Lookup


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>.*"

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]