public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM] archer-sergiodj-cpp-template-lookup: [C++-template-lookup] Import of the first patch.
@ 2012-05-22 15:49 sergiodj
0 siblings, 0 replies; only message in thread
From: sergiodj @ 2012-05-22 15:49 UTC (permalink / raw)
To: archer-commits
The branch, archer-sergiodj-cpp-template-lookup has been updated
via 656062dbd8105c467acfa7434f1c8a58d8afe94d (commit)
from c46b4e83e39b3a044212841d43d03b23841cf0f6 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email.
- Log -----------------------------------------------------------------
commit 656062dbd8105c467acfa7434f1c8a58d8afe94d
Author: Sergio Durigan Junior <sergiodj@redhat.com>
Date: Tue May 22 12:48:05 2012 -0300
[C++-template-lookup] Import of the first patch.
URL: http://sourceware.org/ml/gdb-patches/2010-07/msg00284.html
-----------------------------------------------------------------------
Summary of changes:
gdb/cp-name-parser.y | 9 ++-
gdb/cp-support.c | 68 +++++++++++++++++++++-
gdb/cp-support.h | 4 +
gdb/dwarf2read.c | 21 +++++++
gdb/symtab.c | 61 ++++++++++++++++++++
gdb/symtab.h | 11 ++++
gdb/testsuite/gdb.cp/cp-relocate.exp | 4 +
gdb/testsuite/gdb.cp/temp-op.cc | 105 ++++++++++++++++++++++++++++++++++
gdb/testsuite/gdb.cp/temp-op.exp | 68 ++++++++++++++++++++++
gdb/valops.c | 2 +-
10 files changed, 348 insertions(+), 5 deletions(-)
create mode 100644 gdb/testsuite/gdb.cp/temp-op.cc
create mode 100644 gdb/testsuite/gdb.cp/temp-op.exp
First 500 lines of diff:
diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y
index 6767fa5..0158774 100644
--- a/gdb/cp-name-parser.y
+++ b/gdb/cp-name-parser.y
@@ -2058,9 +2058,12 @@ cp_merge_demangle_parse_infos (struct demangle_parse_info *dest,
cp_demangled_name_parse_free (src);
}
-/* Convert a demangled name to a demangle_component tree. On success,
- a structure containing the root of the new tree is returned; it must
- be freed by calling cp_demangled_name_parse_free. 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 bafdb86..467e9ab 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -833,6 +833,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:
@@ -1069,7 +1135,7 @@ overload_list_add_symbol (struct symbol *sym,
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 03ccb73..ff07184 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -161,6 +161,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 6ddf236..33fea34 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -13281,6 +13281,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
if (name)
{
const char *linkagename;
+ const char *search_name = NULL;
int suppress_add = 0;
if (space)
@@ -13302,6 +13303,26 @@ new_symbol_full (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 46c365c..b5ef6fc 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -490,7 +490,33 @@ 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. */
@@ -883,6 +909,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);
}
@@ -1907,6 +1935,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
@@ -1927,10 +1967,31 @@ 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 = block_iter_name_first (block, name, &iter);
sym != NULL;
sym = block_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 526fe5a..9888025 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -83,6 +83,11 @@ struct probe;
struct cplus_specific
{
const 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,
@@ -167,6 +172,12 @@ extern void symbol_set_demangled_name (struct general_symbol_info *, char *,
extern const char *symbol_get_demangled_name
(const struct general_symbol_info *);
+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
diff --git a/gdb/testsuite/gdb.cp/cp-relocate.exp b/gdb/testsuite/gdb.cp/cp-relocate.exp
index 2981228..e658c7b 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..f48582f
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/temp-op.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/>.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set testfile temp-op
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ untested "Couldn't compile test program"
+ return -1
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+############################################
+
+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 feb47f5..563c9ea 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -2686,7 +2686,7 @@ find_overload_match (struct value **args, int nargs,
hooks/post-receive
--
Repository for Project Archer.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2012-05-22 15:49 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-05-22 15:49 [SCM] archer-sergiodj-cpp-template-lookup: [C++-template-lookup] Import of the first patch sergiodj
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).