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).