From: sami wagiaalla <swagiaal@redhat.com>
To: gdb-patches@sourceware.org
Subject: [patch 2/3] Template Lookup
Date: Mon, 19 Jul 2010 15:29:00 -0000 [thread overview]
Message-ID: <4C446F49.5070204@redhat.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 755 bytes --]
Patch 1 in this series introduced a pseudo-regression. If the symbol
table contained:
foo<int>(int)
foo<char>(char)
Bar<int>
Bar<char>
and the user did:
(gdb) print foo
or
(gdb) ptype Bar
they would get the results for an arbitrary match of foo and Bar where
previously the would just get a "symbol not found" error just because
template lookup did not work properly.
This patch corrects that by introducing a meta variable representing the
template into the scope of the template instance. This symbol is a place
holder until overload resolution, but if the user tries to evaluate it
or print its type they receive an appropriate error message:
"Symbol represents a template and cannot be evaluated."
"type = Template Symbol"
respectively.
[-- Attachment #2: template_lookup_2.patch --]
[-- Type: text/plain, Size: 12143 bytes --]
Add template meta-variable.
2010-07-16 Sami Wagiaalla <swagiaal@redhat.com>
* valops.c (find_overload_match): Handle TYPE_CODE_TEMPLATE.
* symtab.h: Added LOC_TEMPLATE to address_class.
* findvar.c (read_var_value): Handle LOC_TEMPLATE.
* dwarf2read.c (add_template_variable): New function.
(new_symbol): Moved template symbol handling to
add_template_variable().
* c-typeprint.c (c_type_print_varspec_prefix): Handle
TYPE_CODE_TEMPLATE.
(c_type_print_varspec_suffix): Ditto.
(c_type_print_base): Ditto.
* gdbtypes.h: Ditto.
2010-07-16 Sami Wagiaalla <swagiaal@redhat.com>
* gdb.cp/templates.exp: Added the case of "type = Template Symbol"
as an acceptable result for ptype of template symbols.
* gdb.cp/temp-op.exp: Added overload testing.
* gdb.cp/temp-op.cc: Ditto.
diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
index d07fb8f..ad0bfcb 100644
--- a/gdb/c-typeprint.c
+++ b/gdb/c-typeprint.c
@@ -311,6 +311,7 @@ c_type_print_varspec_prefix (struct type *type, struct ui_file *stream,
case TYPE_CODE_COMPLEX:
case TYPE_CODE_NAMESPACE:
case TYPE_CODE_DECFLOAT:
+ case TYPE_CODE_TEMPLATE:
/* These types need no prefix. They are listed here so that
gcc -Wall will reveal any types that haven't been handled. */
break;
@@ -644,6 +645,7 @@ c_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
case TYPE_CODE_COMPLEX:
case TYPE_CODE_NAMESPACE:
case TYPE_CODE_DECFLOAT:
+ case TYPE_CODE_TEMPLATE:
/* These types do not need a suffix. They are listed so that
gcc -Wall will report types that may not have been considered. */
break;
@@ -1134,6 +1136,10 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
fputs_filtered (TYPE_TAG_NAME (type), stream);
break;
+ case TYPE_CODE_TEMPLATE:
+ fputs_filtered ("Template Symbol", stream);
+ break;
+
default:
/* Handle types not explicitly handled by the other cases,
such as fundamental types. For these, just print whatever
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index e4abd23..6659968 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -8636,6 +8636,78 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
SYMBOL_CLASS (sym) = LOC_COMPUTED;
}
+static void
+add_template_variable (struct symbol *symbol, struct pending **listhead,
+ struct objfile *objfile)
+{
+ const struct pending *iterator = *listhead;
+ struct symbol *template_sym;
+ struct symbol *iterator_sym;
+ struct type *type;
+ char *name = SYMBOL_NATURAL_NAME (symbol);
+ char *search_name;
+ char *tmp;
+ int i;
+
+ struct cleanup *all_cleanups = make_cleanup (null_cleanup, NULL);
+
+ gdb_assert (name != NULL);
+
+ /* Remove template parameters from the symbol's name
+ and set its search name. */
+ tmp = cp_remove_template_params (name);
+
+ gdb_assert (tmp != NULL);
+ make_cleanup(xfree, tmp);
+
+ if (strcmp (tmp, name) == 0)
+ return;
+
+ search_name = obsavestring (tmp, strlen (tmp),
+ &objfile->objfile_obstack);
+
+ symbol_set_cplus_search_name (&symbol->ginfo,
+ objfile,
+ search_name);
+
+ /* Has a template symbol for this symbol been added already ? */
+ for (iterator = *(listhead);
+ iterator != NULL;
+ iterator = iterator->next)
+ {
+ for (i = iterator->nsyms - 1; i >= 0; --i)
+ {
+ iterator_sym = iterator->symbol[i];
+
+ if (TYPE_CODE (SYMBOL_TYPE (iterator_sym)) == TYPE_CODE_TEMPLATE
+ && strcmp (SYMBOL_SEARCH_NAME(iterator_sym), search_name) == 0)
+ {
+ do_cleanups (all_cleanups);
+ return;
+ }
+ }
+ }
+
+ /* 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));
+
+ 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;
+
+ SYMBOL_DOMAIN (template_sym) = VAR_DOMAIN;
+ SYMBOL_CLASS (template_sym) = LOC_TEMPLATE;
+
+ add_symbol_to_list (template_sym, listhead);
+
+ do_cleanups (all_cleanups);
+
+}
+
/* Given a pointer to a DWARF information entry, figure out if we need
to make a symbol table entry for it, and if so, create a new entry
and return a pointer to it.
@@ -8681,26 +8753,6 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
(char *) dwarf2_full_name (name, die, cu),
NULL);
- /* For C++ if the name contains template parameters remove them, and set
- the cleaned up name to be the search name. */
- if (cu->language == language_cplus && linkagename
- && cp_name_has_template_parameters (linkagename))
- {
- char *tmp = cp_remove_template_params (linkagename);
-
- if (tmp != NULL && strcmp (tmp, linkagename) != 0)
- {
- search_name = obsavestring (tmp, strlen (tmp),
- &objfile->objfile_obstack);
-
- symbol_set_cplus_search_name (&sym->ginfo,
- objfile,
- search_name);
- }
-
- xfree (tmp);
- }
-
/* Default assumptions.
Use the passed type or decode it from the die. */
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
@@ -8970,7 +9022,15 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
}
if (list_to_add != NULL)
- add_symbol_to_list (sym, list_to_add);
+ {
+ /* For C++ if the name contains template parameters remove them, and set
+ the cleaned up name to be the search name. */
+ if (cu->language == language_cplus && sym->ginfo.name
+ && cp_name_has_template_parameters (sym->ginfo.name))
+ add_template_variable (sym, list_to_add, objfile);
+
+ add_symbol_to_list (sym, list_to_add);
+ }
/* For the benefit of old versions of GCC, check for anonymous
namespaces based on the demangled name. */
diff --git a/gdb/findvar.c b/gdb/findvar.c
index e0ca12c..f4749b7 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -567,6 +567,10 @@ read_var_value (struct symbol *var, struct frame_info *frame)
set_value_optimized_out (v, 1);
return v;
+ case LOC_TEMPLATE:
+ error (_("Symbol represents a template and cannot be evaluated."));
+ break;
+
default:
error (_("Cannot look up value of a botched symbol."));
break;
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index ce79dc2..6fc47f2 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -139,7 +139,12 @@ enum type_code
TYPE_CODE_MODULE, /* Fortran module. */
/* Internal function type. */
- TYPE_CODE_INTERNAL_FUNCTION
+ TYPE_CODE_INTERNAL_FUNCTION,
+
+ /* Types with this code are artificial types created to
+ serve as the root for the instantiations of a given
+ template. */
+ TYPE_CODE_TEMPLATE
};
/* For now allow source to use TYPE_CODE_CLASS for C++ classes, as an
diff --git a/gdb/symtab.h b/gdb/symtab.h
index d3d85cf..67dddeb 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -519,6 +519,10 @@ enum address_class
/* The variable's address is computed by a set of location
functions (see "struct symbol_computed_ops" below). */
LOC_COMPUTED,
+
+ /* The variable is a meta variable representing a template
+ and has no location. */
+ LOC_TEMPLATE
};
/* The methods needed to implement LOC_COMPUTED. These methods can
diff --git a/gdb/testsuite/gdb.cp/temp-op.cc b/gdb/testsuite/gdb.cp/temp-op.cc
index 6d4b13d..b423c26 100644
--- a/gdb/testsuite/gdb.cp/temp-op.cc
+++ b/gdb/testsuite/gdb.cp/temp-op.cc
@@ -9,21 +9,35 @@ int foo (T, char)
return 11;
}
+template<typename T>
+int foo (T, int)
+{
+ T t;
+ return 1112;
+}
+
+template<typename T>
+int foo (T, float)
+{
+ T t;
+ return 1113;
+}
+
template<typename T, typename T2>
-int foo2 (T, T2, char)
+int foo (T, T2, char)
{
T t;
- return 11;
+ return 112;
}
namespace C
{
namespace D {
template<typename T, typename T2>
- int foo3 (T, T2, char)
+ int foo (T, T2, char)
{
T t;
- return 11;
+ return 113;
}
}
}
@@ -85,8 +99,10 @@ int main ()
foo (a, 'a');
foo (a, 1);
- foo2 (a, a, 'a');
- C::D::foo3 (a, a, 'a');
+ foo (a, 1.0f);
+
+ foo (a, a, 'a');
+ C::D::foo (a, a, 'a');
a << 22;
a < 22;
diff --git a/gdb/testsuite/gdb.cp/temp-op.exp b/gdb/testsuite/gdb.cp/temp-op.exp
index f48582f..bb4385b 100644
--- a/gdb/testsuite/gdb.cp/temp-op.exp
+++ b/gdb/testsuite/gdb.cp/temp-op.exp
@@ -40,8 +40,18 @@ if ![runto_main] then {
}
# Test that a templated function can be found
-# with out specification of template arguments
-gdb_test "p foo(a, 'a')" "= 11"
+# with out specification of template arguments.
+gdb_test "p foo(a, 'a')" "= 11"
+
+# Test that overload resolution is still performed
+# correctly.
+gdb_test "p foo(a, 1)" "= 1112"
+gdb_test "p foo(a, 1.0f)" "= 1113"
+
+# Test that fully qualifed names names are not
+# confused.
+gdb_test "p foo(a, a, 'a')" "= 112"
+gdb_test "p C::D::foo (a, a, 'a')" "= 113"
# Test that function names with '<' in their names
# are not mistaken for templates
@@ -64,5 +74,5 @@ gdb_test "p b == 'a'" "= 18"
# Test that printing the a template name without
# template parameters does not return an arbitrary match
-gdb_test "p foo" "No symbol \"foo\" in current context"
-gdb_test "ptype B" "No symbol \"foo\" in current context"
+gdb_test "print foo" "Symbol represents a template and cannot be evaluated."
+gdb_test "ptype B" "type = Template Symbol"
diff --git a/gdb/testsuite/gdb.cp/templates.exp b/gdb/testsuite/gdb.cp/templates.exp
index 33cccc1..e3e0531 100644
--- a/gdb/testsuite/gdb.cp/templates.exp
+++ b/gdb/testsuite/gdb.cp/templates.exp
@@ -282,6 +282,9 @@ gdb_test_multiple "ptype Foo" "ptype Foo" {
# GCC 2.95.3, stabs+ output.
pass "ptype Foo"
}
+ -re "type = Template Symbol\r\n$gdb_prompt $" {
+ pass "ptype Foo"
+ }
}
# -re "type = class Foo<int> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int foo(int, int);\r\n\\}\r\n$gdb_prompt $"
@@ -365,6 +368,9 @@ gdb_test_multiple "ptype Bar" "ptype Bar" {
# GCC 2.95.3, stabs+ output.
pass "ptype Bar"
}
+ -re "type = Template Symbol\r\n$gdb_prompt $" {
+ pass "ptype Bar"
+ }
}
@@ -412,6 +418,9 @@ gdb_test_multiple "ptype Baz" "ptype Baz" {
# GCC 2.95.3, stabs+ output.
pass "ptype Baz"
}
+ -re "type = Template Symbol\r\n$gdb_prompt $" {
+ pass "ptype Baz"
+ }
}
@@ -458,6 +467,9 @@ gdb_test_multiple "ptype Qux" "ptype Qux" {
# GCC 2.95.3, stabs+ output.
pass "ptype Qux"
}
+ -re "type = Template Symbol\r\n$gdb_prompt $" {
+ pass "ptype Qux"
+ }
}
# pt Qux<int,&string>
@@ -496,6 +508,9 @@ gdb_test_multiple "ptype Spec" "ptype Spec" {
# GCC 2.95.3, stabs+ output.
pass "ptype Spec"
}
+ -re "type = Template Symbol\r\n$gdb_prompt $" {
+ pass "ptype Qux"
+ }
}
# pt Spec<char,0>
diff --git a/gdb/valops.c b/gdb/valops.c
index 59ec3ee..f1eb041 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -2458,13 +2458,16 @@ find_overload_match (struct type **arg_types, int nargs,
if (fsym)
{
+ enum type_code code = TYPE_CODE (check_typedef (SYMBOL_TYPE (fsym)));
qualified_name = SYMBOL_SEARCH_NAME (fsym);
/* If we have a function with a C++ name, try to extract just
the function part. Do not try this for non-functions (e.g.
function pointers). */
+
if (qualified_name
- && TYPE_CODE (check_typedef (SYMBOL_TYPE (fsym))) == TYPE_CODE_FUNC)
+ && (code == TYPE_CODE_FUNC
+ || code == TYPE_CODE_TEMPLATE))
{
char *temp;
next reply other threads:[~2010-07-19 15:29 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-19 15:29 sami wagiaalla [this message]
2010-08-18 21:59 ` Tom Tromey
2010-08-26 19:18 ` sami wagiaalla
2010-09-23 18:43 ` [patch 2/4] " sami wagiaalla
2010-09-27 9:27 ` sami wagiaalla
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4C446F49.5070204@redhat.com \
--to=swagiaal@redhat.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).