From patchwork Thu Mar 19 16:16:48 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Schimpe, Christina" X-Patchwork-Id: 131986 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id 80C754B1A28E for ; Thu, 19 Mar 2026 16:17:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 80C754B1A28E Authentication-Results: sourceware.org; dkim=fail reason="signature verification failed" (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=Yy+ZVnqv X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.13]) by sourceware.org (Postfix) with ESMTPS id 02F884B358BB for ; Thu, 19 Mar 2026 16:16:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 02F884B358BB Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=intel.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 02F884B358BB Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=192.198.163.13 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1773937019; cv=none; b=wSsPn47I5cx6nTlqMS3iKsmmN4grQsCAQ20HKGd1M5P+N+LEapWtoErJNFYorm4Ug4ejR3l8My7V8vw4CHjhdgRgftny7kdn5CJ2a6fNKXglMz/5K6XxU7RRnbEF9/On6lyIxXX0cRWTMAnN85/fDQbdaHkSTkcydNpJ4BKB/2g= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1773937019; c=relaxed/simple; bh=8e5PT7sJ+E8+o5IBsHUIokq2IFzBm0oNIgtXp44Z+Ws=; h=DKIM-Signature:MIME-Version:From:To:Subject:Date:Message-Id: MIME-Version; b=vzTW9RNcFXHwlJIvOMJfSOdRlgvQkGfC0CCMduF3S+hUlR1fw11Wctriwy61ju5emDX8AFxO7IpNTAA4dvNqBya8zQUYNjoQrQfQxrX6bABxg9jZeWwswJ5IiRZvo64JMd8v+U6LR/yCMw9sW5AcQwicthD1cDqmt+/mXc/gCls= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 02F884B358BB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1773937019; x=1805473019; h=from:to:subject:date:message-id; bh=8e5PT7sJ+E8+o5IBsHUIokq2IFzBm0oNIgtXp44Z+Ws=; b=Yy+ZVnqvGhtqjbty8dMK81aysDquHMLwr7sD8lMHRIHnN63ollum+61y 8tu+jE5f9UCk+z96qRhBnvTLJEuigdFq5XJ03HINuTl2A5pJKe2XGpbzn RfvHYcaXruANxhHZbE8HLj8nCgwB3+MxTD+fXaIRtmrTPGNVaVOA3Ku++ SYKrBpok/zVz6C4nAswHJBjuH5fOmuus7sx1b/hkbSEmR+XEOCyyPS1vC 2WgDN4W6qMTx/i9HKSiKyZlt0rMRu5d2jlp20XpYX2TMGpHffQ/H865lF 3Y+m1UME6neAoSEJcfIxaOSHMNW/PIU4UkKN2wHMt46BQQ+SNkyk5mnVV w==; X-CSE-ConnectionGUID: Fv61Qd8hSHaDGs0orz02HQ== X-CSE-MsgGUID: Z9IhBv6TRHydDnNdjcZmQw== X-IronPort-AV: E=McAfee;i="6800,10657,11734"; a="77619881" X-IronPort-AV: E=Sophos;i="6.23,129,1770624000"; d="scan'208";a="77619881" MIME-Version: 1.0 Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Mar 2026 09:16:58 -0700 X-CSE-ConnectionGUID: Wnk4LwvkRye0pUnstIMEkg== X-CSE-MsgGUID: qzYoXwKMQE+ipFhcdq1Lag== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.23,129,1770624000"; d="scan'208";a="222121292" Received: from gkldtt-dev-004.igk.intel.com (HELO localhost) ([10.123.221.202]) by orviesa006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Mar 2026 09:16:57 -0700 From: Christina Schimpe To: gdb-patches@sourceware.org Subject: [PATCH 1/1] gdb: Print template arguments of function templates. Date: Thu, 19 Mar 2026 16:16:48 +0000 Message-Id: <20260319161648.1251301-1-christina.schimpe@intel.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-Spam-Status: No, score=-9.2 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, HTML_MESSAGE, RCVD_IN_DNSWL_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_NONE, SPF_NONE, TXREP, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~patchwork=sourceware.org@sourceware.org For function templates currently no template arguments are printed. Add the list of template arguments to function types and print them, similar to struct, class or union types. From now on we print template functions as follows: ~~~ (gdb) ptype func type = int (int, float) [with T = int, U = float] (gdb) print func $6 = {int (int, float) [with T = int, U = float]} 0x4012a0 (int, float)> ~~~ Fix the existing tests for template functions to expect the new output. Reviewed-By: Keith Seitz --- gdb/c-lang.c | 6 +++ gdb/c-lang.h | 10 ++++ gdb/c-typeprint.c | 31 ++++++++----- gdb/dwarf2/read.c | 20 +++++++- gdb/testsuite/gdb.cp/cp-relocate.exp | 4 +- gdb/testsuite/gdb.cp/cpexprs.exp.tcl | 46 +++++++++---------- .../template-specification-full-name.exp | 3 +- 7 files changed, 82 insertions(+), 38 deletions(-) diff --git a/gdb/c-lang.c b/gdb/c-lang.c index fdb5be7b2b7..69ec47cd215 100644 --- a/gdb/c-lang.c +++ b/gdb/c-lang.c @@ -941,6 +941,12 @@ class cplus_language : public language_defn const struct type_print_options *flags) const override { c_print_type (type, varstring, stream, show, level, la_language, flags); + + /* Print target type or template arguments if TYPE it is a function + template. */ + if (type->code () == TYPE_CODE_FUNC) + c_type_print_template_args (flags, type, stream, la_language); + } /* See language.h. */ diff --git a/gdb/c-lang.h b/gdb/c-lang.h index 7d9eaf8571b..538d007e2e6 100644 --- a/gdb/c-lang.h +++ b/gdb/c-lang.h @@ -134,4 +134,14 @@ extern int c_textual_element_type (struct type *, char); extern gdb::unique_xmalloc_ptr c_canonicalize_name (const char *name); +/* Display template arguments of TYPE in the style [with T = ..., U = ...] + based on FLAGS and LANGUAGE on STREAM. + TYPE is the type whose template arguments are being displayed. + It can be a struct/class/union or a function. */ + +extern void c_type_print_template_args (const type_print_options *flags, + type *type, + ui_file *stream, + language language); + #endif /* GDB_C_LANG_H */ diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c index 821b78becf4..a4a3914909b 100644 --- a/gdb/c-typeprint.c +++ b/gdb/c-typeprint.c @@ -786,22 +786,26 @@ c_type_print_varspec_suffix (struct type *type, } } -/* A helper for c_type_print_base_struct_union that displays template - parameters. - - TYPE is the type whose template arguments are being displayed. - - STREAM is the stream on which to print. */ +/* See c-lang.h. */ -static void -c_type_print_template_args (const struct type_print_options *flags, - struct type *type, struct ui_file *stream, - enum language language) +void +c_type_print_template_args (const type_print_options *flags, type *type, + ui_file *stream, language language) { + gdb_assert (type->code () == TYPE_CODE_STRUCT + || type->code () == TYPE_CODE_UNION + || type->code () == TYPE_CODE_FUNC); + if (flags->raw || TYPE_N_TEMPLATE_ARGUMENTS (type) == 0) return; stream->wrap_here (4); + + /* For functions we have to add a space here, for struct/class/unions + this is already taken care of in c_type_print_base_struct_union. */ + if (type->code () == TYPE_CODE_FUNC) + gdb_puts (" ", stream); + gdb_printf (stream, _("[with ")); for (int i = 0; i < TYPE_N_TEMPLATE_ARGUMENTS (type); ++i) @@ -823,7 +827,12 @@ c_type_print_template_args (const struct type_print_options *flags, print_variable_value (sym, {}, stream, 0, language_def (language)); } - gdb_puts (_("] "), stream); + gdb_puts (_("]"), stream); + + /* For struct/class/unions printing of the type is not complete yet, so + we have to add a space here. */ + if (type->code () != TYPE_CODE_FUNC) + gdb_puts (" ", stream); } /* Use 'print_spaces', but take into consideration the diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 8b87d58dd9c..1eff94de246 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -7915,7 +7915,25 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) /* If we've finished processing a top-level function, subsequent symbols go in the file symbol list. */ if (cu->get_builder ()->outermost_context_p ()) - cu->list_in_scope = &cu->get_builder ()->get_file_symbols (); + cu->list_in_scope = &cu->get_builder ()->get_file_symbols (); + + /* In case of C++ functions, add template parameters to the type, similar + to class/struct/union types handled in process_structure_scope. */ + if (!template_args.empty () && cu->lang () == language_cplus) + { + struct type *type = get_die_type (die, cu); + gdb_assert (type != nullptr && type->code () == TYPE_CODE_FUNC); + + ALLOCATE_CPLUS_STRUCT_TYPE (type); + TYPE_N_TEMPLATE_ARGUMENTS (type) = template_args.size (); + TYPE_TEMPLATE_ARGUMENTS (type) + = XOBNEWVEC (&objfile->objfile_obstack, + struct symbol *, + TYPE_N_TEMPLATE_ARGUMENTS (type)); + memcpy (TYPE_TEMPLATE_ARGUMENTS (type), + template_args.data (), + (TYPE_N_TEMPLATE_ARGUMENTS (type) * sizeof (struct symbol *))); + } } /* Process all the DIES contained within a lexical block scope. Start diff --git a/gdb/testsuite/gdb.cp/cp-relocate.exp b/gdb/testsuite/gdb.cp/cp-relocate.exp index fb45313466b..81f03ce64e8 100644 --- a/gdb/testsuite/gdb.cp/cp-relocate.exp +++ b/gdb/testsuite/gdb.cp/cp-relocate.exp @@ -54,11 +54,11 @@ gdb_file_cmd ${binfile} set func1_name "" set func2_name "" gdb_test_multiple "info functions func<.>" "info functions" { - -re "\tint (\[^\r\]*func<1>\[^\r]*);" { + -re "\tint (\[^\r\]*func<1>\[^\r]*) \\\[with X = 1\\\];" { set func1_name $expect_out(1,string) exp_continue } - -re "\tint (\[^\r\]*func<2>\[^\r]*);" { + -re "\tint (\[^\r\]*func<2>\[^\r]*) \\\[with X = 2\\\];" { set func2_name $expect_out(1,string) exp_continue } diff --git a/gdb/testsuite/gdb.cp/cpexprs.exp.tcl b/gdb/testsuite/gdb.cp/cpexprs.exp.tcl index 085dfdd0678..a6c6df959fc 100644 --- a/gdb/testsuite/gdb.cp/cpexprs.exp.tcl +++ b/gdb/testsuite/gdb.cp/cpexprs.exp.tcl @@ -449,95 +449,95 @@ add {tclass::do_something} \ - \ - add {flubber} \ - {void (void)} \ + {void (void) [with A = int, B = int, C = int, D = int, E = int]} \ - \ flubber add {flubber} \ - {void (void)} \ + {void (void) [with A = int, B = int, C = int, D = int, E = short]} \ - \ flubber add {flubber} \ - {void (void)} \ + {void (void) [with A = int, B = int, C = int, D = int, E = long]} \ - \ flubber add {flubber} \ - {void (void)} \ + {void (void) [with A = int, B = int, C = int, D = int, E = char]} \ - \ flubber add {flubber} \ - {void (void)} \ + {void (void) [with A = int, B = int, C = int, D = short, E = int]} \ - \ flubber add {flubber} \ - {void (void)} \ + {void (void) [with A = int, B = int, C = int, D = short, E = short]} \ - \ flubber add {flubber} \ - {void (void)} \ + {void (void) [with A = int, B = int, C = int, D = short, E = long]} \ - \ flubber add {flubber} \ - {void (void)} \ + {void (void) [with A = int, B = int, C = int, D = short, E = char]} \ - \ flubber add {flubber} \ - {void (void)} \ + {void (void) [with A = int, B = int, C = int, D = long, E = int]} \ - \ flubber add {flubber} \ - {void (void)} \ + {void (void) [with A = int, B = int, C = int, D = long, E = short]} \ - \ flubber add {flubber} \ - {void (void)} \ + {void (void) [with A = int, B = int, C = int, D = long, E = long]} \ - \ flubber add {flubber} \ - {void (void)} \ + {void (void) [with A = int, B = int, C = int, D = long, E = char]} \ - \ flubber add {flubber} \ - {void (void)} \ + {void (void) [with A = int, B = int, C = int, D = char, E = int]} \ - \ flubber add {flubber} \ - {void (void)} \ + {void (void) [with A = int, B = int, C = int, D = char, E = short]} \ - \ flubber add {flubber} \ - {void (void)} \ + {void (void) [with A = int, B = int, C = int, D = char, E = long]} \ - \ flubber add {flubber} \ - {void (void)} \ + {void (void) [with A = int, B = int, C = int, D = char, E = char]} \ - \ flubber add {flubber} \ - {void (void)} \ + {void (void) [with A = int, B = int, C = short, D = int, E = int]} \ - \ flubber add {flubber} \ - {void (void)} \ + {void (void) [with A = int, B = int, C = short, D = int, E = short]} \ - \ flubber add {flubber} \ - {void (void)} \ + {void (void) [with A = int, B = int, C = short, D = int, E = long]} \ - \ flubber add {flubber} \ - {void (void)} \ + {void (void) [with A = int, B = int, C = short, D = int, E = char]} \ - \ flubber add {flubber} \ - {void (void)} \ + {void (void) [with A = int, B = int, C = short, D = short, E = int]} \ - \ flubber add {flubber} \ - {void (void)} \ + {void (void) [with A = short, B = int, C = short, D = int, E = short]} \ - \ flubber add {flubber} \ - {void (void)} \ + {void (void) [with A = long, B = short, C = long, D = short, E = long]} \ - \ flubber add {tclass::do_something} \ diff --git a/gdb/testsuite/gdb.dwarf2/template-specification-full-name.exp b/gdb/testsuite/gdb.dwarf2/template-specification-full-name.exp index eea7106d701..714a59f3568 100644 --- a/gdb/testsuite/gdb.dwarf2/template-specification-full-name.exp +++ b/gdb/testsuite/gdb.dwarf2/template-specification-full-name.exp @@ -81,4 +81,5 @@ if {![runto_main]} { } # Just a sanity check to make sure GDB slurped the symbols correctly. -gdb_test "print apply" " = {void \\(void\\)} $hex \\(\\)>" +gdb_test "print apply" \ + " = {void \\(void\\) \\\[with T = int\\\]} $hex \\(\\)>"