From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18389 invoked by alias); 23 Sep 2010 14:48:04 -0000 Received: (qmail 18347 invoked by uid 22791); 23 Sep 2010 14:48:01 -0000 X-SWARE-Spam-Status: No, hits=-5.4 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; Thu, 23 Sep 2010 14:47:55 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o8NElr9K027071 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 23 Sep 2010 10:47:53 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o8NElqV2026430 for ; Thu, 23 Sep 2010 10:47:52 -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 o8NElpew015273 for ; Thu, 23 Sep 2010 10:47:51 -0400 Message-ID: <4C9B6898.1000300@redhat.com> Date: Thu, 23 Sep 2010 18:43:00 -0000 From: sami wagiaalla User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.8) Gecko/20100806 Fedora/3.1.2-1.fc13 Lightning/1.0b2pre Thunderbird/3.1.2 MIME-Version: 1.0 To: gdb-patches@sourceware.org Subject: Re: [patch 2/4] Template Lookup References: <4C446F49.5070204@redhat.com> <4C76BDC8.9030209@redhat.com> In-Reply-To: <4C76BDC8.9030209@redhat.com> Content-Type: multipart/mixed; boundary="------------060703020200030202060903" 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-09/txt/msg00406.txt.bz2 This is a multi-part message in MIME format. --------------060703020200030202060903 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 548 On 08/26/2010 03:17 PM, sami wagiaalla wrote: >> >> Sami> + /* Has a template symbol for this symbol been added already ? */ >> Sami> + for (iterator = *(listhead); >> Sami> + iterator != NULL; >> Sami> + iterator = iterator->next) >> >> I think this means that adding template symbols is O(N^2). >> A temporary hash table for recording this info would be better. >> > > Hmm.. I can't think of an elegant way to do this. I think we can do this, but this patch is just an update to accommodate the refactoring in the other patches in the series. --------------060703020200030202060903 Content-Type: text/x-patch; name="template_lookup_2.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="template_lookup_2.patch" Content-length: 14109 Template Lookup 2: Add template meta-symbol. 2010-09-15 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_meta_symbol): New function. (set_template_symbol_search_name): New function. (new_symbol): Moved template symbol handling to add_template_meta_symbol(). * 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-09-15 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 test for a function with templated paramters. * gdb.cp/temp-op.cc: Ditto. * 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 926ae2f..4fde7e5 100644 --- a/gdb/c-typeprint.c +++ b/gdb/c-typeprint.c @@ -312,6 +312,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; @@ -645,6 +646,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; @@ -1159,6 +1161,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 8d37db1..dcdd086 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -3670,6 +3670,44 @@ partial_die_full_name (struct partial_die_info *pdi, return typename_concat (NULL, parent_scope, pdi->name, 0, cu); } +/* The give symbol SYMBOL is template instance symbol with template + parameters in its name. This function removes the template parameters + from the name and makes the resulting cleaned name SYMBOL's + search_name. */ + +static char * +set_template_symbol_search_name (struct general_symbol_info *gsym, + struct objfile *objfile) +{ + char *name = symbol_natural_name (gsym); + char *search_name = NULL; + char *tmp; + + 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); + + if (tmp == NULL) + return NULL; + + make_cleanup (xfree, tmp); + + /* If template parameters were indeed removed, set the search name. */ + if (strcmp (tmp, name) != 0) + { + search_name = obsavestring (tmp, strlen (tmp), &objfile->objfile_obstack); + + symbol_set_cplus_search_name (gsym, objfile, search_name); + } + + do_cleanups (all_cleanups); + return search_name; +} + static void add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) { @@ -10473,6 +10511,61 @@ var_decode_location (struct attribute *attr, struct symbol *sym, SYMBOL_CLASS (sym) = LOC_COMPUTED; } +/* Given a template symbol SYMBOL this function removes the template + parameters from the symbol name, and sets its search name to that. + If no instances of the same template were encountered before a + meta symbol representing the template is inserted into the current + scope. */ + +static void +add_template_meta_symbol (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 *search_name; + int i; + + search_name = set_template_symbol_search_name (&symbol->ginfo, objfile); + + if (search_name == NULL) + /* This is not a template symbol. */ + return; + + /* 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) + return; + } + } + + /* This is a new template therefore 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); +} + /* 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. @@ -10502,7 +10595,6 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu, { const char *linkagename; int suppress_add = 0; - const char *search_name = NULL; if (space) sym = space; @@ -10523,26 +10615,6 @@ 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; @@ -10851,7 +10923,15 @@ new_symbol_full (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_meta_symbol (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 dba7284..1b4c31c 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 9892289..a1fba1c 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -523,6 +523,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..1ee2a4e 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; } } } @@ -67,6 +81,10 @@ int operator== (B, char){ return 18; } +int operator== (B, char){ + return 19; +} + template class Outer{ public: @@ -85,8 +103,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; @@ -99,6 +119,10 @@ int main () b == 1; b == 'a'; + B bc; + bc == 'a'; + + Outer::Inner::ReallyInner<5> oir; return 0; diff --git a/gdb/testsuite/gdb.cp/temp-op.exp b/gdb/testsuite/gdb.cp/temp-op.exp index b480d13..21e644f 100644 --- a/gdb/testsuite/gdb.cp/temp-op.exp +++ b/gdb/testsuite/gdb.cp/temp-op.exp @@ -27,8 +27,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 @@ -48,8 +58,10 @@ gdb_test "p a == 1" "= 16" gdb_test "p b == 1" "= 17" gdb_test "p b == 'a'" "= 18" +gdb_test "p bc == 'a'" "= 19" + # 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 a6b7fe6..c2d9c3e 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -2456,13 +2456,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; --------------060703020200030202060903--