This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [patch 4/4] Template Lookup
- From: sami wagiaalla <swagiaal at redhat dot com>
- To: gdb-patches at sourceware dot org
- Date: Thu, 23 Sep 2010 10:48:04 -0400
- Subject: Re: [patch 4/4] Template Lookup
- References: <4C446F1C.60507@redhat.com> <4C460A3E.2040004@redhat.com> <m3pqxfa934.fsf@fleche.redhat.com> <4C7690B4.7020504@redhat.com> <m339tufnez.fsf@fleche.redhat.com>
On 08/31/2010 06:05 PM, Tom Tromey wrote:
"Sami" == sami wagiaalla<swagiaal@redhat.com> writes:
Sami> Hmm.. can you give me an example of this ? I tried to construct an
Sami> example with an extern function but I learned that cplus does not
Sami> allow extern template functions.
Ordinarily, to make a test involving psymtab expansion, you have to make
two compilation units.
[...]
Thanks for the compact example. I made it into a test case and added
partial symbol support.
The attached patch was regression tested on x8664 with gcc-4.4.4-10.f13
Sami
Template Lookup 4: Support template lookup for partial symbols.
2010-09-17 Sami Wagiaalla <swagiaal@redhat.com>
* psymtab.c (lookup_partial_symbol): Support search of template
symbols.
* dwarf2read.c (add_partial_symbol): set search name for
template symbols.
2010-09-17 Sami Wagiaalla <swagiaal@redhat.com>
* gdb.cp/partial.exp: New file.
* gdb.cp/partial2.cc: New file.
* gdb.cp/partial1.cc: New file.
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 0d3a34b..b9e3ecb 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -3869,6 +3869,14 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
break;
}
+ /* For C++ if the name contains template parameters remove them, and set
+ the cleaned up name to be the search name. */
+ if (psym
+ && cu->language == language_cplus
+ && actual_name
+ && cp_name_has_template_parameters (actual_name))
+ set_template_symbol_search_name (&((struct partial_symbol *) psym)->ginfo, objfile);
+
if (built_actual_name)
xfree (actual_name);
}
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index 6b29e85..07656cc 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -32,6 +32,8 @@
#include "command.h"
#include "readline/readline.h"
#include "gdb_regex.h"
+#include "cp-support.h"
+#include "language.h"
#ifndef DEV_TTY
#define DEV_TTY "/dev/tty"
@@ -451,6 +453,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
struct partial_symbol **top, **real_top, **bottom, **center;
int length = (global ? pst->n_global_syms : pst->n_static_syms);
int do_linear_search = 1;
+ const char *template_name = NULL;
if (length == 0)
{
@@ -460,6 +463,17 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
pst->objfile->global_psymbols.list + pst->globals_offset :
pst->objfile->static_psymbols.list + pst->statics_offset);
+ if (current_language->la_language == language_cplus
+ && cp_name_has_template_parameters (name))
+ {
+ template_name = name;
+ name = cp_remove_template_params (name);
+
+ if (name == NULL)
+ /* Not a legal C++ name. */
+ return NULL;
+ }
+
if (global) /* This means we can use a binary search. */
{
do_linear_search = 0;
@@ -498,6 +512,10 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
while (top <= real_top
&& SYMBOL_MATCHES_SEARCH_NAME (*top, name))
{
+ if (template_name != NULL
+ && !SYMBOL_MATCHES_TEMPLATE_NAME (*top, template_name))
+ continue;
+
if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
SYMBOL_DOMAIN (*top), domain))
return (*top);
@@ -512,6 +530,10 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
{
for (psym = start; psym < start + length; psym++)
{
+ if (template_name != NULL
+ && !SYMBOL_MATCHES_TEMPLATE_NAME (*psym, template_name))
+ continue;
+
if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym),
SYMBOL_DOMAIN (*psym), domain)
&& SYMBOL_MATCHES_SEARCH_NAME (*psym, name))
diff --git a/gdb/testsuite/gdb.cp/partial.exp b/gdb/testsuite/gdb.cp/partial.exp
new file mode 100644
index 0000000..86ac84a
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/partial.exp
@@ -0,0 +1,68 @@
+# Copyright 2008 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Test evaluation of template function for partial symbols.
+
+set testfile "partial"
+
+set srcfile1 "${testfile}1.cc"
+set srcfile2 "${testfile}2.cc"
+set objfile1 "${testfile}1.o"
+set objfile2 "${testfile}2.o"
+
+set binfile "${objdir}/${subdir}/${testfile}"
+
+if { [gdb_compile "$srcdir/$subdir/$srcfile1" "$objdir/$subdir/$objfile1" object {debug c++}] != "" } {
+ untested m-static.exp
+ return -1
+}
+
+if { [gdb_compile "$srcdir/$subdir/$srcfile2" "$objdir/$subdir/$objfile2" object {debug c++}] != "" } {
+ untested m-static.exp
+ return -1
+}
+
+if { [gdb_compile "$objdir/$subdir/$objfile1 $objdir/$subdir/$objfile2" "${binfile}" executable {debug c++}] != "" } {
+ untested m-static.exp
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+# Test proper printing of template function.
+gdb_test "p foo(11)" "= 11"
+
+# Test printing of template function by including
+# template argument.
+gdb_test "p foo<double>(11)" "= 11"
+
+# Test printing of template function by including
+# template argument.
+gdb_test "p foo<fake>(11)" {No symbol "foo<fake>" in current context.}
+
+# Same as above but with some overloading.
+gdb_test "p bar(1,1)" "= 22"
+gdb_test "p bar('a','a')" "= 33"
+
+gdb_test "ptype bar<int>" {= double \(int, int\)}
+gdb_test "ptype bar<char>" {= double \(char, char\)}
diff --git a/gdb/testsuite/gdb.cp/partial1.cc b/gdb/testsuite/gdb.cp/partial1.cc
new file mode 100644
index 0000000..2251680
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/partial1.cc
@@ -0,0 +1,6 @@
+extern int g(void);
+
+int main()
+{
+ return g();
+}
diff --git a/gdb/testsuite/gdb.cp/partial2.cc b/gdb/testsuite/gdb.cp/partial2.cc
new file mode 100644
index 0000000..708c8f4
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/partial2.cc
@@ -0,0 +1,10 @@
+
+template<typename T> double foo (T x) { return x; }
+template<typename T> double bar (T x, int) { return 22; }
+template<typename T> double bar (T x, char) { return 33; }
+
+int g (void)
+{
+ return foo(1.0) + foo(2)
+ + bar(1,1) + bar('a','a');
+}