From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19106 invoked by alias); 19 Jul 2010 15:29:24 -0000 Received: (qmail 19088 invoked by uid 22791); 19 Jul 2010 15:29:22 -0000 X-SWARE-Spam-Status: No, hits=-5.3 required=5.0 tests=AWL,BAYES_00,KAM_STOCKGEN,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,TW_BJ,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 19 Jul 2010 15:29:15 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o6JFTDXD027734 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 19 Jul 2010 11:29:14 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o6JFTDL7008561 for ; Mon, 19 Jul 2010 11:29:13 -0400 Received: from [10.15.16.129] (dhcp-10-15-16-129.yyz.redhat.com [10.15.16.129]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id o6JFTD7R019782 for ; Mon, 19 Jul 2010 11:29:13 -0400 Message-ID: <4C446F49.5070204@redhat.com> Date: Mon, 19 Jul 2010 15:29:00 -0000 From: sami wagiaalla User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.10) Gecko/20100621 Fedora/3.0.5-1.fc13 Thunderbird/3.0.5 MIME-Version: 1.0 To: gdb-patches@sourceware.org Subject: [patch 2/3] Template Lookup Content-Type: multipart/mixed; boundary="------------010402030507070507030707" X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-07/txt/msg00285.txt.bz2 This is a multi-part message in MIME format. --------------010402030507070507030707 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 755 Patch 1 in this series introduced a pseudo-regression. If the symbol table contained: foo(int) foo(char) Bar Bar 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. --------------010402030507070507030707 Content-Type: text/plain; name="template_lookup_2.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="template_lookup_2.patch" Content-length: 12143 Add template meta-variable. 2010-07-16 Sami Wagiaalla * 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 * 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 +int foo (T, int) +{ + T t; + return 1112; +} + +template +int foo (T, float) +{ + T t; + return 1113; +} + template -int foo2 (T, T2, char) +int foo (T, T2, char) { T t; - return 11; + return 112; } namespace C { namespace D { template - 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 \\{\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 @@ -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 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; --------------010402030507070507030707--