From: sami wagiaalla <swagiaal@redhat.com>
To: gdb-patches@sourceware.org
Subject: Re: [patch 1/3] Template Lookup
Date: Tue, 20 Jul 2010 20:42:00 -0000 [thread overview]
Message-ID: <4C460A3E.2040004@redhat.com> (raw)
In-Reply-To: <4C446F1C.60507@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 41 bytes --]
Same patch but using prepare_for_testing
[-- Attachment #2: template_lookup_1.patch --]
[-- Type: text/plain, Size: 15887 bytes --]
Create search_name and fixed template lookup
2010-07-15 Sami Wagiaalla <swagiaal@redhat.com>
* valops.c (find_overload_match): Use SYMBOL_SEARCH_NAME instead of
SYMBOL_NATURAL_NAME.
* symtab.h: Added new member search_name to cplus_specific.
(symbol_set_cplus_search_name): New function prototype.
(symbol_get_cplus_search_name): New function prototype.
* symtab.c (symbol_set_cplus_search_name): New function.
(symbol_get_cplus_search_name): New function.
(symbol_search_name): Handle the C++ case.
(symbol_matches_template_name): New function.
* dwarf2read.c (new_symbol): Set search_name of C++ template symbols.
* cp-support.H (cp_name_has_template_parameters): New function
prototype.
(cp_remove_template_params): New function ptototype.
* cp-support.c (cp_name_has_template_parameters): New function.
(cp_remove_template_params_component): New function.
(cp_remove_template_params): New function.
(overload_list_add_symbol): Use SYMBOL_SEARCH_NAME instead of
SYMBOL_NATURAL_NAME.
* cp-name-parser.y (cp_demangled_name_to_comp): Added more detail to
comment.
2010-07-15 Sami Wagiaalla <swagiaal@redhat.com>
* gdb.cp/temp-op.exp: New test.
* gdb.cp/temp-op.cc: New test.
* gdb.cp/cp-relocate.exp: Set the language C++.
diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y
index 6d7b600..c9b5747 100644
--- a/gdb/cp-name-parser.y
+++ b/gdb/cp-name-parser.y
@@ -1966,9 +1966,12 @@ cp_comp_to_string (struct demangle_component *result, int estimated_len)
&err);
}
-/* Convert a demangled name to a demangle_component tree. On success,
- the root of the new tree is returned; it is valid until the next
- call to this function and should not be freed. On error, NULL is
+/* Convert a demangled name to a demangle_component tree. The structure
+ of the tree depends on the format of each node in the tree. For
+ information on the structure of a node see the comment corresponding
+ to its type in demangle_component_type.
+ On success, the root of the new tree is returned; it is valid until the
+ next call to this function and should not be freed. On error, NULL is
returned, and an error message will be set in *ERRMSG (which does
not need to be freed). */
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index 41af7ae..4ef1a0a 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -428,6 +428,72 @@ cp_remove_params (const char *demangled_name)
return ret;
}
+/* Returns 1 if the given name contains template parameters;
+ otherwise return 0.
+ Used as a quick heuristic to avoid more expensive template
+ parsing when not necessary. */
+
+int
+cp_name_has_template_parameters (const char *name)
+{
+ char *c = strchr (name, '<');
+ return c != NULL && strchr (c+1, '>') != NULL;
+}
+
+/* Remove template parameters components from the give tree. */
+
+static struct demangle_component *
+cp_remove_template_params_component (struct demangle_component *comp)
+{
+
+ gdb_assert (comp != NULL);
+
+ switch (comp->type)
+ {
+ case DEMANGLE_COMPONENT_TEMPLATE:
+ /* If there is a template component remove this node by re-parenting the
+ the left child. */
+ comp = d_left (comp);
+ break;
+ case DEMANGLE_COMPONENT_QUAL_NAME:
+ /* For a qualified name remove template components from the right
+ subtree. */
+ d_right (comp) = cp_remove_template_params_component (d_right (comp));
+ break;
+ case DEMANGLE_COMPONENT_TYPED_NAME:
+ /* Template components, if present, will be in the left subtree. Remove
+ them. */
+ d_left (comp) = cp_remove_template_params_component (d_left (comp));
+ break;
+ default:
+ break;
+ }
+
+ return comp;
+}
+
+/* Remove template parameters from the given name. The returned string is
+ malloc'ed and must be properly saved and freed. */
+
+char *
+cp_remove_template_params (const char *name)
+{
+ struct demangle_component *ret_comp;
+ char *ret = NULL;
+
+ if (name == NULL)
+ return NULL;
+
+ ret_comp = cp_demangled_name_to_comp (name, NULL);
+ if (ret_comp == NULL)
+ return NULL;
+
+ ret_comp = cp_remove_template_params_component (ret_comp);
+ ret = cp_comp_to_string (ret_comp, 10);
+
+ return ret;
+}
+
/* Here are some random pieces of trivia to keep in mind while trying
to take apart demangled names:
@@ -661,7 +727,7 @@ overload_list_add_symbol (struct symbol *sym, const char *oload_name)
return;
/* Get the demangled name without parameters */
- sym_name = cp_remove_params (SYMBOL_NATURAL_NAME (sym));
+ sym_name = cp_remove_params (SYMBOL_SEARCH_NAME (sym));
if (!sym_name)
return;
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index ddc4c93..a2c8f7f 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -107,6 +107,10 @@ extern char *cp_func_name (const char *full_name);
extern char *cp_remove_params (const char *demangled_name);
+extern int cp_name_has_template_parameters (const char *name);
+
+extern char *cp_remove_template_params (const char *name);
+
extern struct symbol **make_symbol_overload_list (const char *,
const char *);
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index a8692ea..e4abd23 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -8661,6 +8661,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
if (name)
{
const char *linkagename;
+ const char *search_name = NULL;
sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
sizeof (struct symbol));
@@ -8680,6 +8681,26 @@ 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;
diff --git a/gdb/symtab.c b/gdb/symtab.c
index ec0e809..ef9824d 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -389,6 +389,30 @@ symbol_get_demangled_name (const struct general_symbol_info *gsymbol)
return gsymbol->language_specific.mangled_lang.demangled_name;
}
+/* Set the search name of the give GSYMBOL to name. */
+void
+symbol_set_cplus_search_name (struct general_symbol_info *gsymbol,
+ struct objfile *objfile,
+ const char *name)
+{
+ if (gsymbol->language_specific.cplus_specific == NULL)
+ symbol_init_cplus_specific (gsymbol, objfile);
+
+ gsymbol->language_specific.cplus_specific->search_name = (char *) name;
+}
+
+/* Get the search name of the give GSYMBOL. */
+
+char*
+symbol_get_cplus_search_name (const struct general_symbol_info *gsymbol)
+{
+ if (gsymbol->language_specific.cplus_specific != NULL
+ && gsymbol->language_specific.cplus_specific->search_name != NULL)
+ return gsymbol->language_specific.cplus_specific->search_name;
+
+ return symbol_natural_name (gsymbol);
+}
+
\f
/* Initialize the language dependent portion of a symbol
depending upon the language for the symbol. */
@@ -754,6 +778,8 @@ symbol_search_name (const struct general_symbol_info *gsymbol)
{
if (gsymbol->language == language_ada)
return gsymbol->name;
+ else if (gsymbol->language == language_cplus)
+ return symbol_get_cplus_search_name (gsymbol);
else
return symbol_natural_name (gsymbol);
}
@@ -1657,6 +1683,18 @@ find_main_filename (void)
return (NULL);
}
+/* Return 1 if NAME matches SYM's template name. */
+
+static int
+symbol_matches_template_name (const char *name, struct symbol *sym)
+{
+ const char *template_name = SYMBOL_NATURAL_NAME(sym);
+ if (template_name == NULL)
+ return 0;
+
+ return strcmp_iw (template_name, name) == 0;
+}
+
/* Search BLOCK for symbol NAME in DOMAIN.
Note that if NAME is the demangled form of a C++ symbol, we will fail
@@ -1678,10 +1716,29 @@ lookup_block_symbol (const struct block *block, const char *name,
if (!BLOCK_FUNCTION (block))
{
+ const char *template_name = NULL;
+
+ 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;
+ }
+
for (sym = dict_iter_name_first (BLOCK_DICT (block), name, &iter);
sym != NULL;
sym = dict_iter_name_next (name, &iter))
{
+ /* For C++ if the name being searched for contains template
+ parameters check the template name of the symbol. */
+ if (template_name != NULL
+ && !symbol_matches_template_name (template_name, sym))
+ continue;
+
if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
SYMBOL_DOMAIN (sym), domain))
return sym;
diff --git a/gdb/symtab.h b/gdb/symtab.h
index e6ab26f..d3d85cf 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -80,6 +80,11 @@ struct program_space;
struct cplus_specific
{
char *demangled_name;
+
+ /* If the symbol name contains template parameters this is the name with
+ these parameters removed to be used during search. Otherwise this
+ should be NULL, and the regular symbol name should be used. */
+ char *search_name;
};
/* Define a structure for the information that is common to all symbol types,
@@ -166,6 +171,13 @@ extern void symbol_set_demangled_name (struct general_symbol_info *, char *,
extern char *symbol_get_demangled_name (const struct general_symbol_info *);
+/* Set the template name of the give GSYMBOL to name. */
+extern void symbol_set_cplus_search_name (struct general_symbol_info *gsymbol,
+ struct objfile *objfile,
+ const char *name);
+
+extern char* symbol_get_cplus_search_name (const struct general_symbol_info *);
+
extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, struct obj_section *);
/* Note that all the following SYMBOL_* macros are used with the
@@ -273,6 +285,7 @@ extern char *symbol_demangled_name (const struct general_symbol_info *symbol);
(symbol_search_name (&(symbol)->ginfo))
extern char *symbol_search_name (const struct general_symbol_info *);
+
/* Analogous to SYMBOL_MATCHES_NATURAL_NAME, but uses the search
name. */
#define SYMBOL_MATCHES_SEARCH_NAME(symbol, name) \
diff --git a/gdb/testsuite/gdb.cp/cp-relocate.exp b/gdb/testsuite/gdb.cp/cp-relocate.exp
index 30d362a..880ad38 100644
--- a/gdb/testsuite/gdb.cp/cp-relocate.exp
+++ b/gdb/testsuite/gdb.cp/cp-relocate.exp
@@ -52,6 +52,8 @@ gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_file_cmd ${binfile}
+gdb_test_no_output "set language c++" ""
+
# Find the interesting functions. We go to a little effort to find
# the right function names here, to work around PR c++/40.
set func1_name ""
@@ -123,6 +125,8 @@ gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
+gdb_test_no_output "set language c++" ""
+
gdb_test "add-symbol-file ${binfile} 0 -s ${func1_sec} 0x10000 -s ${func2_sec} 0x20000" \
"Reading symbols from .*${testfile}\\.o\\.\\.\\.done\\.(|\r\nUsing host libthread_db library .*libthread_db.so.*\\.)" \
"add-symbol-file ${testfile}.o" \
diff --git a/gdb/testsuite/gdb.cp/temp-op.cc b/gdb/testsuite/gdb.cp/temp-op.cc
new file mode 100644
index 0000000..6d4b13d
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/temp-op.cc
@@ -0,0 +1,105 @@
+class A
+{
+};
+
+template<typename T>
+int foo (T, char)
+{
+ T t;
+ return 11;
+}
+
+template<typename T, typename T2>
+int foo2 (T, T2, char)
+{
+ T t;
+ return 11;
+}
+
+namespace C
+{
+ namespace D {
+ template<typename T, typename T2>
+ int foo3 (T, T2, char)
+ {
+ T t;
+ return 11;
+ }
+ }
+}
+int operator<< (A, int)
+{
+ return 12;
+}
+
+int operator< (A, int)
+{
+ return 13;
+}
+
+int operator<= (A, int)
+{
+ return 14;
+}
+
+template<typename T>
+int operator==(T, char)
+{
+ return 15;
+}
+
+int operator==(A, int)
+{
+ return 16;
+}
+
+template<typename T>
+class B{
+ T t;
+public:
+ int operator==(int)
+ {
+ return 17;
+ }
+};
+
+int operator== (B<int>, char){
+ return 18;
+}
+
+template <class T, int>
+class Outer{
+ public:
+ template <class T2, int>
+ class Inner{
+ public:
+ template <int>
+ class ReallyInner{};
+ };
+};
+
+
+int main ()
+{
+ A a;
+
+ foo (a, 'a');
+ foo (a, 1);
+ foo2 (a, a, 'a');
+ C::D::foo3 (a, a, 'a');
+
+ a << 22;
+ a < 22;
+ a <= 22;
+
+ a == 'a';
+ a == 1;
+
+ B<int> b;
+ b == 1;
+ b == 'a';
+
+ Outer<int, 23>::Inner<long, 27>::ReallyInner<5> oir;
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.cp/temp-op.exp b/gdb/testsuite/gdb.cp/temp-op.exp
new file mode 100644
index 0000000..b480d13
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/temp-op.exp
@@ -0,0 +1,55 @@
+# 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/>.
+
+set testfile temp-op
+set srcfile ${testfile}.cc
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug c++}] } {
+ return -1
+}
+
+############################################
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint main"
+ continue
+}
+
+# Test that a templated function can be found
+# with out specification of template arguments
+gdb_test "p foo(a, 'a')" "= 11"
+
+# Test that function names with '<' in their names
+# are not mistaken for templates
+gdb_test "p a << 22" "= 12"
+gdb_test "p a < 22" "= 13"
+gdb_test "p a <= 22" "= 14"
+
+# Test that a template operator can be correctly
+# evaluated
+gdb_test "p a == 'a'" "= 15"
+
+# Test that overload resolution is still correctly
+# performed.
+gdb_test "p a == 1" "= 16"
+
+# Test calling a member function of a template class
+gdb_test "p b == 1" "= 17"
+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"
diff --git a/gdb/valops.c b/gdb/valops.c
index 506d40e..59ec3ee 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -2458,7 +2458,7 @@ find_overload_match (struct type **arg_types, int nargs,
if (fsym)
{
- qualified_name = SYMBOL_NATURAL_NAME (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.
next prev parent reply other threads:[~2010-07-20 20:42 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-19 15:28 sami wagiaalla
2010-07-20 20:42 ` sami wagiaalla [this message]
2010-08-18 21:45 ` Tom Tromey
2010-08-26 16:05 ` sami wagiaalla
2010-08-31 22:05 ` Tom Tromey
2010-09-23 18:43 ` [patch 4/4] " sami wagiaalla
2010-09-23 17:55 ` [patch 1/4] " sami wagiaalla
2010-10-05 19:08 ` sami wagiaalla
2010-10-14 15:23 ` sami wagiaalla
2010-11-01 20:15 ` sami wagiaalla
2010-08-11 18:13 ` [patch 1/3] " 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=4C460A3E.2040004@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).