summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuca Di Sera <luca.disera@qt.io>2023-11-21 11:21:21 +0100
committerLuca Di Sera <luca.disera@qt.io>2023-12-05 15:24:14 +0100
commit1e745d04ff91683d87d296a738221cc0d50841cc (patch)
tree03aca7cac9431b00e66ada48a675a6d95da5406e
parentf65c4d534056cc0e6770f084aff3da29d4dea6a1 (diff)
QDoc: Add a regression suite for templated callables
QDoc provides a regression test, "generatedoutput", that, while incomplete, is used to keep track of certain changes that are touch the end-to-end output of a QDoc run. When QDoc processes a project, it extract certain information from the underlying code-base of the proejct. The extracted information are then used to perform certain sanity checks and to build the final output documentation. One such information is the template declaration of certain templated documentable elements in a C++ code-base. Currently, "generatedoutput" provides only a very small surface to track changes to template declarations. While QDoc extracts template declaration, they are not meaningful when performing any sanity checks. For example, when QDoc tries to "match" an "\fn" command to its underlying documentable element, as extracted from the code-base, template declarations are not taken into account. This, in turn, means that two callables that are only distinguishable by their template declaration will be indistinguishable to QDoc, preventing the user from correctly documenting them as separate elements. As this issue will be addressed shortly, QDoc will require changes that can modify the output documentation with regards to template declarations of callable elements. To help in evaluating the effect of those changes, the surface of "generatedoutput" is now increased with a new "test", "templatedCallables". The new test, while not exhaustive due to it being manually mantained, provides some relatively realistic specimens for most base cases of templated callables, so that changes in output can be tracked. A new directory, "templatedCallables", was added under the "testdata" for "generatedoutput". "templatedCallables" defines a QDoc project, based on the general configurations for "generatedoutput", that documents a simple code-base exposing a variety of callable elements that are templated. The code-base for the project lives in two new files, "templated_callables.h", which contains the specimens definitions, and "templated_callables.cpp", which contains a documentation block for each specimen in the project. "tst_generatedoutput.cpp", the main implementation file for the test, was updated to take into consideration the new project, as is required by the updating process for "generatedoutput". The initial regression files for the new project were generated and are now part of the project, under "expected_output". The regression files show a series of errors with regards to the presentation of template declarations, such as missing parameter pack information or default argument initializers. Those errors have been in QDoc for a long time, thus why they are represented in our regression suite, and are expected to be fixed in certain upcoming changes related to template declarations in QDoc. Task-number: QTBUG-118080 Task-number: QTBUG-117881 Change-Id: I21bfb7eba56d34d7872670fe208c2049301c9145 Reviewed-by: Topi Reiniƶ <topi.reinio@qt.io>
-rw-r--r--src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templated-callables-h.html81
-rw-r--r--src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templated-callables-h.webxml66
-rw-r--r--src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templated-callables-h.xml65
-rw-r--r--src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templatedclass.html90
-rw-r--r--src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templatedclass.webxml66
-rw-r--r--src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templatedclass.xml66
-rw-r--r--src/qdoc/qdoc/tests/generatedoutput/testdata/templatedcallables/templated_callables.cpp148
-rw-r--r--src/qdoc/qdoc/tests/generatedoutput/testdata/templatedcallables/templated_callables.h69
-rw-r--r--src/qdoc/qdoc/tests/generatedoutput/testdata/templatedcallables/templatedcallables.qdocconf17
-rw-r--r--src/qdoc/qdoc/tests/generatedoutput/tst_generatedoutput.cpp11
10 files changed, 679 insertions, 0 deletions
diff --git a/src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templated-callables-h.html b/src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templated-callables-h.html
new file mode 100644
index 000000000..f07956b11
--- /dev/null
+++ b/src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templated-callables-h.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+<!-- templated_callables.cpp -->
+ <title>&lt;templated_callables.h&gt; | templatedcallables</title>
+</head>
+<body>
+<div class="sidebar">
+<div class="toc">
+<h3 id="toc">Contents</h3>
+</div>
+<div class="sidebar-content" id="sidebar-content"></div></div>
+<h1 class="title" translate="no">&lt;templated_callables.h&gt;</h1>
+<div class="table"><table class="alignedsummary" translate="no">
+<tr><td class="memItemLeft rightAlign topAlign"> Header:</td><td class="memItemRight bottomAlign"> <span class="preprocessor">#include &lt;templated_callables.h&gt;</span></td></tr>
+</table></div>
+<h2 id="functions">Functions</h2>
+<div class="table"><table class="alignedsummary" translate="no">
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="templated-callables-h.html#templated_function_with_defaulted_non_type_template_parameter" translate="no">templated_function_with_defaulted_non_type_template_parameter</a></b>()</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="templated-callables-h.html#templated_function_with_defaulted_template_template_parameter" translate="no">templated_function_with_defaulted_template_template_parameter</a></b>(Container&lt;T, size&gt;)</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="templated-callables-h.html#templated_function_with_defaulted_type_template_parameter" translate="no">templated_function_with_defaulted_type_template_parameter</a></b>(T)</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="templated-callables-h.html#templated_function_with_non_type_template_parameter" translate="no">templated_function_with_non_type_template_parameter</a></b>()</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="templated-callables-h.html#templated_function_with_non_type_template_parameter_pack" translate="no">templated_function_with_non_type_template_parameter_pack</a></b>()</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="templated-callables-h.html#templated_function_with_placeholder_non_type_template_parameter" translate="no">templated_function_with_placeholder_non_type_template_parameter</a></b>()</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="templated-callables-h.html#templated_function_with_template_template_parameter" translate="no">templated_function_with_template_template_parameter</a></b>(K&lt;T&gt;)</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="templated-callables-h.html#templated_function_with_template_template_parameter_pack" translate="no">templated_function_with_template_template_parameter_pack</a></b>(Container&lt;T&gt;...)</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="templated-callables-h.html#templated_function_with_type_template_parameter" translate="no">templated_function_with_type_template_parameter</a></b>(T)</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="templated-callables-h.html#templated_function_with_type_template_parameter_pack" translate="no">templated_function_with_type_template_parameter_pack</a></b>(Ts...)</td></tr>
+</table></div>
+<!-- $$$<templated_callables.h>-description -->
+<div class="descr">
+<h2 id="details">Detailed Description</h2>
+<p>Containing headers for the tested free functions.</p>
+</div>
+<!-- @@@<templated_callables.h> -->
+<div class="func">
+<h2>Function Documentation</h2>
+<!-- $$$templated_function_with_defaulted_non_type_template_parameter[overload1]$$$templated_function_with_defaulted_non_type_template_parameter -->
+<h3 class="fn" translate="no" id="templated_function_with_defaulted_non_type_template_parameter">template &lt;char Category&gt; <span class="type">void</span> <span class="name">templated_function_with_defaulted_non_type_template_parameter</span>()</h3>
+<p>A templated function with a defaulted non type template parameter.</p>
+<!-- @@@templated_function_with_defaulted_non_type_template_parameter -->
+<!-- $$$templated_function_with_defaulted_template_template_parameter[overload1]$$$templated_function_with_defaulted_template_template_parameterContainer<T,size> -->
+<h3 class="fn" translate="no" id="templated_function_with_defaulted_template_template_parameter">template &lt;typename T, int size, template &lt;typename, int&gt; class Container> <span class="type">void</span> <span class="name">templated_function_with_defaulted_template_template_parameter</span>(<span class="type">Container</span>&lt;<span class="type">T</span>, <span class="type">size</span>&gt;)</h3>
+<p>A templated function with a defaulted template template parameter.</p>
+<!-- @@@templated_function_with_defaulted_template_template_parameter -->
+<!-- $$$templated_function_with_defaulted_type_template_parameter[overload1]$$$templated_function_with_defaulted_type_template_parameterT -->
+<h3 class="fn" translate="no" id="templated_function_with_defaulted_type_template_parameter">template &lt;typename T&gt; <span class="type">void</span> <span class="name">templated_function_with_defaulted_type_template_parameter</span>(<span class="type">T</span>)</h3>
+<p>A templated function with a defaulted type template parameter.</p>
+<!-- @@@templated_function_with_defaulted_type_template_parameter -->
+<!-- $$$templated_function_with_non_type_template_parameter[overload1]$$$templated_function_with_non_type_template_parameter -->
+<h3 class="fn" translate="no" id="templated_function_with_non_type_template_parameter">template &lt;char Category&gt; <span class="type">void</span> <span class="name">templated_function_with_non_type_template_parameter</span>()</h3>
+<p>A templated function with a non-defaulted non type template parameter.</p>
+<!-- @@@templated_function_with_non_type_template_parameter -->
+<!-- $$$templated_function_with_non_type_template_parameter_pack[overload1]$$$templated_function_with_non_type_template_parameter_pack -->
+<h3 class="fn" translate="no" id="templated_function_with_non_type_template_parameter_pack">template &lt;unsigned int Weights&gt; <span class="type">void</span> <span class="name">templated_function_with_non_type_template_parameter_pack</span>()</h3>
+<p>A templated function with a non type template parameter pack.</p>
+<!-- @@@templated_function_with_non_type_template_parameter_pack -->
+<!-- $$$templated_function_with_placeholder_non_type_template_parameter[overload1]$$$templated_function_with_placeholder_non_type_template_parameter -->
+<h3 class="fn" translate="no" id="templated_function_with_placeholder_non_type_template_parameter">template &lt;auto Iterator&gt; <span class="type">void</span> <span class="name">templated_function_with_placeholder_non_type_template_parameter</span>()</h3>
+<p>A templated function with a placeholder non type template parameter.</p>
+<!-- @@@templated_function_with_placeholder_non_type_template_parameter -->
+<!-- $$$templated_function_with_template_template_parameter[overload1]$$$templated_function_with_template_template_parameterK<T> -->
+<h3 class="fn" translate="no" id="templated_function_with_template_template_parameter">template &lt;typename T, template &lt;typename&gt; class K> <span class="type">void</span> <span class="name">templated_function_with_template_template_parameter</span>(<span class="type">K</span>&lt;<span class="type">T</span>&gt;)</h3>
+<p>A templated function with a non-defaulted template template parameter.</p>
+<!-- @@@templated_function_with_template_template_parameter -->
+<!-- $$$templated_function_with_template_template_parameter_pack[overload1]$$$templated_function_with_template_template_parameter_packContainer<T>... -->
+<h3 class="fn" translate="no" id="templated_function_with_template_template_parameter_pack">template &lt;typename T, template &lt;typename&gt; class Container> <span class="type">void</span> <span class="name">templated_function_with_template_template_parameter_pack</span>(<span class="type">Container</span>&lt;<span class="type">T</span>&gt;...)</h3>
+<p>A templated function with a template template parameter pack.</p>
+<!-- @@@templated_function_with_template_template_parameter_pack -->
+<!-- $$$templated_function_with_type_template_parameter[overload1]$$$templated_function_with_type_template_parameterT -->
+<h3 class="fn" translate="no" id="templated_function_with_type_template_parameter">template &lt;typename T&gt; <span class="type">void</span> <span class="name">templated_function_with_type_template_parameter</span>(<span class="type">T</span>)</h3>
+<p>A templated function with a non-defaulted type template parameter.</p>
+<!-- @@@templated_function_with_type_template_parameter -->
+<!-- $$$templated_function_with_type_template_parameter_pack[overload1]$$$templated_function_with_type_template_parameter_packTs... -->
+<h3 class="fn" translate="no" id="templated_function_with_type_template_parameter_pack">template &lt;typename Ts&gt; <span class="type">void</span> <span class="name">templated_function_with_type_template_parameter_pack</span>(<span class="type">Ts</span>...)</h3>
+<p>A templated function with a type template parameter pack.</p>
+<!-- @@@templated_function_with_type_template_parameter_pack -->
+</div>
+</body>
+</html>
diff --git a/src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templated-callables-h.webxml b/src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templated-callables-h.webxml
new file mode 100644
index 000000000..8ae7ad257
--- /dev/null
+++ b/src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templated-callables-h.webxml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<WebXML>
+ <document>
+ <header name="&lt;templated_callables.h&gt;" href="templated-callables-h.html" status="active" documented="true" module="TestQDoc" title="&lt;templated_callables.h&gt;" fulltitle="&lt;templated_callables.h&gt;" subtitle="">
+ <description>
+ <para>Containing headers for the tested free functions.</para>
+ </description>
+ <function name="templated_function_with_defaulted_non_type_template_parameter" href="templated-callables-h.html#templated_function_with_defaulted_non_type_template_parameter" status="active" access="public" location="templated_callables.h" documented="true" related="0" meta="plain" type="void" signature="void templated_function_with_defaulted_non_type_template_parameter()">
+ <description>
+ <para>A templated function with a defaulted non type template parameter.</para>
+ </description>
+ </function>
+ <function name="templated_function_with_defaulted_template_template_parameter" href="templated-callables-h.html#templated_function_with_defaulted_template_template_parameter" status="active" access="public" location="templated_callables.h" documented="true" related="1" meta="plain" type="void" signature="void templated_function_with_defaulted_template_template_parameter(Container&lt;T, size&gt;)">
+ <parameter type="Container&lt;T, size&gt;" name="" default=""/>
+ <description>
+ <para>A templated function with a defaulted template template parameter.</para>
+ </description>
+ </function>
+ <function name="templated_function_with_defaulted_type_template_parameter" href="templated-callables-h.html#templated_function_with_defaulted_type_template_parameter" status="active" access="public" location="templated_callables.h" documented="true" related="2" meta="plain" type="void" signature="void templated_function_with_defaulted_type_template_parameter(T)">
+ <parameter type="T" name="" default=""/>
+ <description>
+ <para>A templated function with a defaulted type template parameter.</para>
+ </description>
+ </function>
+ <function name="templated_function_with_non_type_template_parameter" href="templated-callables-h.html#templated_function_with_non_type_template_parameter" status="active" access="public" location="templated_callables.h" documented="true" related="3" meta="plain" type="void" signature="void templated_function_with_non_type_template_parameter()">
+ <description>
+ <para>A templated function with a non-defaulted non type template parameter.</para>
+ </description>
+ </function>
+ <function name="templated_function_with_non_type_template_parameter_pack" href="templated-callables-h.html#templated_function_with_non_type_template_parameter_pack" status="active" access="public" location="templated_callables.h" documented="true" related="4" meta="plain" type="void" signature="void templated_function_with_non_type_template_parameter_pack()">
+ <description>
+ <para>A templated function with a non type template parameter pack.</para>
+ </description>
+ </function>
+ <function name="templated_function_with_placeholder_non_type_template_parameter" href="templated-callables-h.html#templated_function_with_placeholder_non_type_template_parameter" status="active" access="public" location="templated_callables.h" documented="true" related="5" meta="plain" type="void" signature="void templated_function_with_placeholder_non_type_template_parameter()">
+ <description>
+ <para>A templated function with a placeholder non type template parameter.</para>
+ </description>
+ </function>
+ <function name="templated_function_with_template_template_parameter" href="templated-callables-h.html#templated_function_with_template_template_parameter" status="active" access="public" location="templated_callables.h" documented="true" related="6" meta="plain" type="void" signature="void templated_function_with_template_template_parameter(K&lt;T&gt;)">
+ <parameter type="K&lt;T&gt;" name="" default=""/>
+ <description>
+ <para>A templated function with a non-defaulted template template parameter.</para>
+ </description>
+ </function>
+ <function name="templated_function_with_template_template_parameter_pack" href="templated-callables-h.html#templated_function_with_template_template_parameter_pack" status="active" access="public" location="templated_callables.h" documented="true" related="7" meta="plain" type="void" signature="void templated_function_with_template_template_parameter_pack(Container&lt;T&gt;...)">
+ <parameter type="Container&lt;T&gt;..." name="" default=""/>
+ <description>
+ <para>A templated function with a template template parameter pack.</para>
+ </description>
+ </function>
+ <function name="templated_function_with_type_template_parameter" href="templated-callables-h.html#templated_function_with_type_template_parameter" status="active" access="public" location="templated_callables.h" documented="true" related="8" meta="plain" type="void" signature="void templated_function_with_type_template_parameter(T)">
+ <parameter type="T" name="" default=""/>
+ <description>
+ <para>A templated function with a non-defaulted type template parameter.</para>
+ </description>
+ </function>
+ <function name="templated_function_with_type_template_parameter_pack" href="templated-callables-h.html#templated_function_with_type_template_parameter_pack" status="active" access="public" location="templated_callables.h" documented="true" related="9" meta="plain" type="void" signature="void templated_function_with_type_template_parameter_pack(Ts...)">
+ <parameter type="Ts..." name="" default=""/>
+ <description>
+ <para>A templated function with a type template parameter pack.</para>
+ </description>
+ </function>
+ </header>
+ </document>
+</WebXML>
diff --git a/src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templated-callables-h.xml b/src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templated-callables-h.xml
new file mode 100644
index 000000000..2a7204642
--- /dev/null
+++ b/src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templated-callables-h.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<db:article xmlns:db="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.2" xml:lang="en">
+<db:info>
+<db:title>&lt;templated_callables.h&gt;</db:title>
+<db:productname>templatedcallables</db:productname>
+<db:titleabbrev>templatedcallables Reference Documentation</db:titleabbrev>
+<db:abstract>
+<db:para>templatedcallables Reference Documentation.</db:para></db:abstract>
+</db:info>
+<db:variablelist>
+<db:varlistentry>
+<db:term>Header</db:term>
+<db:listitem>
+<db:para>templated_callables.h</db:para>
+</db:listitem>
+</db:varlistentry>
+</db:variablelist>
+<db:section xml:id="details">
+<db:title>Detailed Description</db:title>
+<db:para>Containing headers for the tested free functions.</db:para>
+</db:section>
+<db:section xml:id="function-documentation">
+<db:title>Function Documentation</db:title>
+<db:section xml:id="templated_function_with_defaulted_non_type_template_parameter">
+<db:title>void templated_function_with_defaulted_non_type_template_parameter()</db:title>
+<db:para>A templated function with a defaulted non type template parameter.</db:para>
+</db:section>
+<db:section xml:id="templated_function_with_defaulted_template_template_parameter">
+<db:title>void templated_function_with_defaulted_template_template_parameter(<db:emphasis>Container&lt;T, size&gt;</db:emphasis>)</db:title>
+<db:para>A templated function with a defaulted template template parameter.</db:para>
+</db:section>
+<db:section xml:id="templated_function_with_defaulted_type_template_parameter">
+<db:title>void templated_function_with_defaulted_type_template_parameter(<db:emphasis>T</db:emphasis>)</db:title>
+<db:para>A templated function with a defaulted type template parameter.</db:para>
+</db:section>
+<db:section xml:id="templated_function_with_non_type_template_parameter">
+<db:title>void templated_function_with_non_type_template_parameter()</db:title>
+<db:para>A templated function with a non-defaulted non type template parameter.</db:para>
+</db:section>
+<db:section xml:id="templated_function_with_non_type_template_parameter_pack">
+<db:title>void templated_function_with_non_type_template_parameter_pack()</db:title>
+<db:para>A templated function with a non type template parameter pack.</db:para>
+</db:section>
+<db:section xml:id="templated_function_with_placeholder_non_type_template_parameter">
+<db:title>void templated_function_with_placeholder_non_type_template_parameter()</db:title>
+<db:para>A templated function with a placeholder non type template parameter.</db:para>
+</db:section>
+<db:section xml:id="templated_function_with_template_template_parameter">
+<db:title>void templated_function_with_template_template_parameter(<db:emphasis>K&lt;T&gt;</db:emphasis>)</db:title>
+<db:para>A templated function with a non-defaulted template template parameter.</db:para>
+</db:section>
+<db:section xml:id="templated_function_with_template_template_parameter_pack">
+<db:title>void templated_function_with_template_template_parameter_pack(<db:emphasis>Container&lt;T&gt;...</db:emphasis>)</db:title>
+<db:para>A templated function with a template template parameter pack.</db:para>
+</db:section>
+<db:section xml:id="templated_function_with_type_template_parameter">
+<db:title>void templated_function_with_type_template_parameter(<db:emphasis>T</db:emphasis>)</db:title>
+<db:para>A templated function with a non-defaulted type template parameter.</db:para>
+</db:section>
+<db:section xml:id="templated_function_with_type_template_parameter_pack">
+<db:title>void templated_function_with_type_template_parameter_pack(<db:emphasis>Ts...</db:emphasis>)</db:title>
+<db:para>A templated function with a type template parameter pack.</db:para>
+</db:section>
+</db:section>
+</db:article>
diff --git a/src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templatedclass.html b/src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templatedclass.html
new file mode 100644
index 000000000..bf8e84012
--- /dev/null
+++ b/src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templatedclass.html
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+<!-- templated_callables.cpp -->
+ <title>TemplatedClass Class | templatedcallables</title>
+</head>
+<body>
+<li>TemplatedClass</li>
+<div class="sidebar">
+<div class="toc">
+<h3 id="toc">Contents</h3>
+<ul>
+<li class="level1"><a href="#public-functions">Public Functions</a></li>
+<li class="level1"><a href="#details">Detailed Description</a></li>
+</ul>
+</div>
+<div class="sidebar-content" id="sidebar-content"></div></div>
+<h1 class="title" translate="no">TemplatedClass Class</h1>
+<span class="small-subtitle" translate="no">template &lt;typename T&gt; class TemplatedClass</span>
+<div class="table"><table class="alignedsummary" translate="no">
+<tr><td class="memItemLeft rightAlign topAlign"> Header:</td><td class="memItemRight bottomAlign"> <span class="preprocessor">#include &lt;TemplatedClass&gt;</span></td></tr>
+</table></div>
+<ul>
+<li><a href="templatedclass-members.html">List of all members, including inherited members</a></li>
+</ul>
+<h2 id="public-functions">Public Functions</h2>
+<div class="table"><table class="alignedsummary" translate="no">
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="templatedclass.html#templated_method_with_defaulted_non_type_template_parameter" translate="no">templated_method_with_defaulted_non_type_template_parameter</a></b>()</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="templatedclass.html#templated_method_with_defaulted_template_template_parameter" translate="no">templated_method_with_defaulted_template_template_parameter</a></b>(Container&lt;U, size&gt;)</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="templatedclass.html#templated_method_with_defaulted_type_template_parameter" translate="no">templated_method_with_defaulted_type_template_parameter</a></b>(U)</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="templatedclass.html#templated_method_with_non_type_template_parameter" translate="no">templated_method_with_non_type_template_parameter</a></b>()</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="templatedclass.html#templated_method_with_non_type_template_parameter_pack" translate="no">templated_method_with_non_type_template_parameter_pack</a></b>()</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="templatedclass.html#templated_method_with_placeholder_non_type_template_parameter" translate="no">templated_method_with_placeholder_non_type_template_parameter</a></b>()</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="templatedclass.html#templated_method_with_template_template_parameter" translate="no">templated_method_with_template_template_parameter</a></b>(X&lt;U&gt;)</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="templatedclass.html#templated_method_with_template_template_parameter_pack" translate="no">templated_method_with_template_template_parameter_pack</a></b>(Container&lt;U&gt;...)</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="templatedclass.html#templated_method_with_type_template_parameter" translate="no">templated_method_with_type_template_parameter</a></b>(U)</td></tr>
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="templatedclass.html#templated_method_with_type_template_parameter_pack" translate="no">templated_method_with_type_template_parameter_pack</a></b>(Ts...)</td></tr>
+</table></div>
+<!-- $$$TemplatedClass-description -->
+<div class="descr">
+<h2 id="details">Detailed Description</h2>
+<p>Containing record for the tested methods.</p>
+</div>
+<!-- @@@TemplatedClass -->
+<div class="func">
+<h2>Member Function Documentation</h2>
+<!-- $$$templated_method_with_defaulted_non_type_template_parameter[overload1]$$$templated_method_with_defaulted_non_type_template_parameter -->
+<h3 class="fn" translate="no" id="templated_method_with_defaulted_non_type_template_parameter">template &lt;int Size&gt; <span class="type">void</span> TemplatedClass::<span class="name">templated_method_with_defaulted_non_type_template_parameter</span>()</h3>
+<p>A templated method under a templated class with a defaulted non type template parameter.</p>
+<!-- @@@templated_method_with_defaulted_non_type_template_parameter -->
+<!-- $$$templated_method_with_defaulted_template_template_parameter[overload1]$$$templated_method_with_defaulted_template_template_parameterContainer<U,size> -->
+<h3 class="fn" translate="no" id="templated_method_with_defaulted_template_template_parameter">template &lt;typename U, int size, template &lt;typename, int&gt; class Container> <span class="type">void</span> TemplatedClass::<span class="name">templated_method_with_defaulted_template_template_parameter</span>(<span class="type">Container</span>&lt;<span class="type">U</span>, <span class="type">size</span>&gt;)</h3>
+<p>A templated method under a templated class with a defaulted template template parameter.</p>
+<!-- @@@templated_method_with_defaulted_template_template_parameter -->
+<!-- $$$templated_method_with_defaulted_type_template_parameter[overload1]$$$templated_method_with_defaulted_type_template_parameterU -->
+<h3 class="fn" translate="no" id="templated_method_with_defaulted_type_template_parameter">template &lt;typename U&gt; <span class="type">void</span> TemplatedClass::<span class="name">templated_method_with_defaulted_type_template_parameter</span>(<span class="type">U</span>)</h3>
+<p>A templated method under a templated class with a defaulted type template parameter.</p>
+<!-- @@@templated_method_with_defaulted_type_template_parameter -->
+<!-- $$$templated_method_with_non_type_template_parameter[overload1]$$$templated_method_with_non_type_template_parameter -->
+<h3 class="fn" translate="no" id="templated_method_with_non_type_template_parameter">template &lt;int Size&gt; <span class="type">void</span> TemplatedClass::<span class="name">templated_method_with_non_type_template_parameter</span>()</h3>
+<p>A templated method under a templated class with a non-defaulted non type template parameter.</p>
+<!-- @@@templated_method_with_non_type_template_parameter -->
+<!-- $$$templated_method_with_non_type_template_parameter_pack[overload1]$$$templated_method_with_non_type_template_parameter_pack -->
+<h3 class="fn" translate="no" id="templated_method_with_non_type_template_parameter_pack">template &lt;int Dimensions&gt; <span class="type">void</span> TemplatedClass::<span class="name">templated_method_with_non_type_template_parameter_pack</span>()</h3>
+<p>A templated method under a templated class with a non type template parameter pack.</p>
+<!-- @@@templated_method_with_non_type_template_parameter_pack -->
+<!-- $$$templated_method_with_placeholder_non_type_template_parameter[overload1]$$$templated_method_with_placeholder_non_type_template_parameter -->
+<h3 class="fn" translate="no" id="templated_method_with_placeholder_non_type_template_parameter">template &lt;auto Predicate&gt; <span class="type">void</span> TemplatedClass::<span class="name">templated_method_with_placeholder_non_type_template_parameter</span>()</h3>
+<p>A templated method under a templated class with a placeholder non type template parameter.</p>
+<!-- @@@templated_method_with_placeholder_non_type_template_parameter -->
+<!-- $$$templated_method_with_template_template_parameter[overload1]$$$templated_method_with_template_template_parameterX<U> -->
+<h3 class="fn" translate="no" id="templated_method_with_template_template_parameter">template &lt;typename U, template &lt;typename&gt; class X> <span class="type">void</span> TemplatedClass::<span class="name">templated_method_with_template_template_parameter</span>(<span class="type">X</span>&lt;<span class="type">U</span>&gt;)</h3>
+<p>A templated method under a templated class with a non-defaulted template template parameter.</p>
+<!-- @@@templated_method_with_template_template_parameter -->
+<!-- $$$templated_method_with_template_template_parameter_pack[overload1]$$$templated_method_with_template_template_parameter_packContainer<U>... -->
+<h3 class="fn" translate="no" id="templated_method_with_template_template_parameter_pack">template &lt;typename U, template &lt;typename&gt; class Container> <span class="type">void</span> TemplatedClass::<span class="name">templated_method_with_template_template_parameter_pack</span>(<span class="type">Container</span>&lt;<span class="type">U</span>&gt;...)</h3>
+<p>A templated method under a templated class with a template template parameter pack.</p>
+<!-- @@@templated_method_with_template_template_parameter_pack -->
+<!-- $$$templated_method_with_type_template_parameter[overload1]$$$templated_method_with_type_template_parameterU -->
+<h3 class="fn" translate="no" id="templated_method_with_type_template_parameter">template &lt;typename U&gt; <span class="type">void</span> TemplatedClass::<span class="name">templated_method_with_type_template_parameter</span>(<span class="type">U</span>)</h3>
+<p>A templated method under a templated class with a non-defaulted type template parameter.</p>
+<!-- @@@templated_method_with_type_template_parameter -->
+<!-- $$$templated_method_with_type_template_parameter_pack[overload1]$$$templated_method_with_type_template_parameter_packTs... -->
+<h3 class="fn" translate="no" id="templated_method_with_type_template_parameter_pack">template &lt;typename Ts&gt; <span class="type">void</span> TemplatedClass::<span class="name">templated_method_with_type_template_parameter_pack</span>(<span class="type">Ts</span>...)</h3>
+<p>A templated method under a templated class with a type template parameter pack.</p>
+<!-- @@@templated_method_with_type_template_parameter_pack -->
+</div>
+</body>
+</html>
diff --git a/src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templatedclass.webxml b/src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templatedclass.webxml
new file mode 100644
index 000000000..29c0bc661
--- /dev/null
+++ b/src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templatedclass.webxml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<WebXML>
+ <document>
+ <class name="TemplatedClass" href="templatedclass.html" status="active" access="public" location="templated_callables.h" documented="true" module="TestQDoc">
+ <description>
+ <para>Containing record for the tested methods.</para>
+ </description>
+ <function name="templated_method_with_defaulted_non_type_template_parameter" fullname="TemplatedClass::templated_method_with_defaulted_non_type_template_parameter" href="templatedclass.html#templated_method_with_defaulted_non_type_template_parameter" status="active" access="public" location="templated_callables.h" documented="true" meta="plain" type="void" signature="void templated_method_with_defaulted_non_type_template_parameter()">
+ <description>
+ <para>A templated method under a templated class with a defaulted non type template parameter.</para>
+ </description>
+ </function>
+ <function name="templated_method_with_defaulted_template_template_parameter" fullname="TemplatedClass::templated_method_with_defaulted_template_template_parameter" href="templatedclass.html#templated_method_with_defaulted_template_template_parameter" status="active" access="public" location="templated_callables.h" documented="true" meta="plain" type="void" signature="void templated_method_with_defaulted_template_template_parameter(Container&lt;U, size&gt;)">
+ <parameter type="Container&lt;U, size&gt;" name="" default=""/>
+ <description>
+ <para>A templated method under a templated class with a defaulted template template parameter.</para>
+ </description>
+ </function>
+ <function name="templated_method_with_defaulted_type_template_parameter" fullname="TemplatedClass::templated_method_with_defaulted_type_template_parameter" href="templatedclass.html#templated_method_with_defaulted_type_template_parameter" status="active" access="public" location="templated_callables.h" documented="true" meta="plain" type="void" signature="void templated_method_with_defaulted_type_template_parameter(U)">
+ <parameter type="U" name="" default=""/>
+ <description>
+ <para>A templated method under a templated class with a defaulted type template parameter.</para>
+ </description>
+ </function>
+ <function name="templated_method_with_non_type_template_parameter" fullname="TemplatedClass::templated_method_with_non_type_template_parameter" href="templatedclass.html#templated_method_with_non_type_template_parameter" status="active" access="public" location="templated_callables.h" documented="true" meta="plain" type="void" signature="void templated_method_with_non_type_template_parameter()">
+ <description>
+ <para>A templated method under a templated class with a non-defaulted non type template parameter.</para>
+ </description>
+ </function>
+ <function name="templated_method_with_non_type_template_parameter_pack" fullname="TemplatedClass::templated_method_with_non_type_template_parameter_pack" href="templatedclass.html#templated_method_with_non_type_template_parameter_pack" status="active" access="public" location="templated_callables.h" documented="true" meta="plain" type="void" signature="void templated_method_with_non_type_template_parameter_pack()">
+ <description>
+ <para>A templated method under a templated class with a non type template parameter pack.</para>
+ </description>
+ </function>
+ <function name="templated_method_with_placeholder_non_type_template_parameter" fullname="TemplatedClass::templated_method_with_placeholder_non_type_template_parameter" href="templatedclass.html#templated_method_with_placeholder_non_type_template_parameter" status="active" access="public" location="templated_callables.h" documented="true" meta="plain" type="void" signature="void templated_method_with_placeholder_non_type_template_parameter()">
+ <description>
+ <para>A templated method under a templated class with a placeholder non type template parameter.</para>
+ </description>
+ </function>
+ <function name="templated_method_with_template_template_parameter" fullname="TemplatedClass::templated_method_with_template_template_parameter" href="templatedclass.html#templated_method_with_template_template_parameter" status="active" access="public" location="templated_callables.h" documented="true" meta="plain" type="void" signature="void templated_method_with_template_template_parameter(X&lt;U&gt;)">
+ <parameter type="X&lt;U&gt;" name="" default=""/>
+ <description>
+ <para>A templated method under a templated class with a non-defaulted template template parameter.</para>
+ </description>
+ </function>
+ <function name="templated_method_with_template_template_parameter_pack" fullname="TemplatedClass::templated_method_with_template_template_parameter_pack" href="templatedclass.html#templated_method_with_template_template_parameter_pack" status="active" access="public" location="templated_callables.h" documented="true" meta="plain" type="void" signature="void templated_method_with_template_template_parameter_pack(Container&lt;U&gt;...)">
+ <parameter type="Container&lt;U&gt;..." name="" default=""/>
+ <description>
+ <para>A templated method under a templated class with a template template parameter pack.</para>
+ </description>
+ </function>
+ <function name="templated_method_with_type_template_parameter" fullname="TemplatedClass::templated_method_with_type_template_parameter" href="templatedclass.html#templated_method_with_type_template_parameter" status="active" access="public" location="templated_callables.h" documented="true" meta="plain" type="void" signature="void templated_method_with_type_template_parameter(U)">
+ <parameter type="U" name="" default=""/>
+ <description>
+ <para>A templated method under a templated class with a non-defaulted type template parameter.</para>
+ </description>
+ </function>
+ <function name="templated_method_with_type_template_parameter_pack" fullname="TemplatedClass::templated_method_with_type_template_parameter_pack" href="templatedclass.html#templated_method_with_type_template_parameter_pack" status="active" access="public" location="templated_callables.h" documented="true" meta="plain" type="void" signature="void templated_method_with_type_template_parameter_pack(Ts...)">
+ <parameter type="Ts..." name="" default=""/>
+ <description>
+ <para>A templated method under a templated class with a type template parameter pack.</para>
+ </description>
+ </function>
+ </class>
+ </document>
+</WebXML>
diff --git a/src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templatedclass.xml b/src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templatedclass.xml
new file mode 100644
index 000000000..427f1cab3
--- /dev/null
+++ b/src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templatedclass.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<db:article xmlns:db="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.2" xml:lang="en">
+<db:info>
+<db:title>TemplatedClass Class</db:title>
+<db:subtitle>template &lt;typename T&gt; class TemplatedClass</db:subtitle>
+<db:productname>templatedcallables</db:productname>
+<db:titleabbrev>templatedcallables Reference Documentation</db:titleabbrev>
+<db:abstract>
+<db:para>templatedcallables Reference Documentation.</db:para></db:abstract>
+</db:info>
+<db:variablelist>
+<db:varlistentry>
+<db:term>Header</db:term>
+<db:listitem>
+<db:para>TemplatedClass</db:para>
+</db:listitem>
+</db:varlistentry>
+</db:variablelist>
+<db:section xml:id="details">
+<db:title>Detailed Description</db:title>
+<db:para>Containing record for the tested methods.</db:para>
+</db:section>
+<db:section xml:id="member-function-documentation">
+<db:title>Member Function Documentation</db:title>
+<db:section xml:id="templated_method_with_defaulted_non_type_template_parameter">
+<db:title>void TemplatedClass::templated_method_with_defaulted_non_type_template_parameter()</db:title>
+<db:para>A templated method under a templated class with a defaulted non type template parameter.</db:para>
+</db:section>
+<db:section xml:id="templated_method_with_defaulted_template_template_parameter">
+<db:title>void TemplatedClass::templated_method_with_defaulted_template_template_parameter(<db:emphasis>Container&lt;U, size&gt;</db:emphasis>)</db:title>
+<db:para>A templated method under a templated class with a defaulted template template parameter.</db:para>
+</db:section>
+<db:section xml:id="templated_method_with_defaulted_type_template_parameter">
+<db:title>void TemplatedClass::templated_method_with_defaulted_type_template_parameter(<db:emphasis>U</db:emphasis>)</db:title>
+<db:para>A templated method under a templated class with a defaulted type template parameter.</db:para>
+</db:section>
+<db:section xml:id="templated_method_with_non_type_template_parameter">
+<db:title>void TemplatedClass::templated_method_with_non_type_template_parameter()</db:title>
+<db:para>A templated method under a templated class with a non-defaulted non type template parameter.</db:para>
+</db:section>
+<db:section xml:id="templated_method_with_non_type_template_parameter_pack">
+<db:title>void TemplatedClass::templated_method_with_non_type_template_parameter_pack()</db:title>
+<db:para>A templated method under a templated class with a non type template parameter pack.</db:para>
+</db:section>
+<db:section xml:id="templated_method_with_placeholder_non_type_template_parameter">
+<db:title>void TemplatedClass::templated_method_with_placeholder_non_type_template_parameter()</db:title>
+<db:para>A templated method under a templated class with a placeholder non type template parameter.</db:para>
+</db:section>
+<db:section xml:id="templated_method_with_template_template_parameter">
+<db:title>void TemplatedClass::templated_method_with_template_template_parameter(<db:emphasis>X&lt;U&gt;</db:emphasis>)</db:title>
+<db:para>A templated method under a templated class with a non-defaulted template template parameter.</db:para>
+</db:section>
+<db:section xml:id="templated_method_with_template_template_parameter_pack">
+<db:title>void TemplatedClass::templated_method_with_template_template_parameter_pack(<db:emphasis>Container&lt;U&gt;...</db:emphasis>)</db:title>
+<db:para>A templated method under a templated class with a template template parameter pack.</db:para>
+</db:section>
+<db:section xml:id="templated_method_with_type_template_parameter">
+<db:title>void TemplatedClass::templated_method_with_type_template_parameter(<db:emphasis>U</db:emphasis>)</db:title>
+<db:para>A templated method under a templated class with a non-defaulted type template parameter.</db:para>
+</db:section>
+<db:section xml:id="templated_method_with_type_template_parameter_pack">
+<db:title>void TemplatedClass::templated_method_with_type_template_parameter_pack(<db:emphasis>Ts...</db:emphasis>)</db:title>
+<db:para>A templated method under a templated class with a type template parameter pack.</db:para>
+</db:section>
+</db:section>
+</db:article>
diff --git a/src/qdoc/qdoc/tests/generatedoutput/testdata/templatedcallables/templated_callables.cpp b/src/qdoc/qdoc/tests/generatedoutput/testdata/templatedcallables/templated_callables.cpp
new file mode 100644
index 000000000..bc6531de5
--- /dev/null
+++ b/src/qdoc/qdoc/tests/generatedoutput/testdata/templatedcallables/templated_callables.cpp
@@ -0,0 +1,148 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only#pragma once
+
+#include "templated_callables.h"
+
+/*!
+ * \headerfile <templated_callables.h>
+ * \inmodule TestQDoc
+ *
+ * Containing headers for the tested free functions.
+ */
+
+/*!
+ * \class TemplatedClass
+ * \inmodule TestQDoc
+ *
+ * Containing record for the tested methods.
+ */
+
+/*!
+ * \fn template<typename T> template <typename U> void TemplatedClass<T>::templated_method_with_type_template_parameter(U)
+ *
+ * A templated method under a templated class with a non-defaulted type template parameter.
+ */
+
+/*!
+ * \fn template<typename T> void templated_function_with_type_template_parameter(T)
+ * \relates <templated_callables.h>
+ *
+ * A templated function with a non-defaulted type template parameter.
+ */
+
+/*!
+ * \fn template<typename T> template <typename U> void TemplatedClass<T>::templated_method_with_defaulted_type_template_parameter(U)
+ *
+ * A templated method under a templated class with a defaulted type template parameter.
+ */
+
+/*!
+ * \fn template<typename T> void templated_function_with_defaulted_type_template_parameter(T)
+ * \relates <templated_callables.h>
+ *
+ * A templated function with a defaulted type template parameter.
+ */
+
+/*!
+ * \fn template<typename T> template <typename... Ts> void TemplatedClass<T>::templated_method_with_type_template_parameter_pack(Ts...)
+ *
+ * A templated method under a templated class with a type template parameter pack.
+ */
+
+/*!
+ * \fn template<typename... Ts> void templated_function_with_type_template_parameter_pack(Ts...)
+ * \relates <templated_callables.h>
+ *
+ * A templated function with a type template parameter pack.
+ */
+
+/*!
+ * \fn template<typename T> template <int Size> void TemplatedClass<T>::templated_method_with_non_type_template_parameter()
+ *
+ * A templated method under a templated class with a non-defaulted non type template parameter.
+ */
+
+/*!
+ * \fn template<char Category> void templated_function_with_non_type_template_parameter()
+ * \relates <templated_callables.h>
+ *
+ * A templated function with a non-defaulted non type template parameter.
+ */
+
+/*!
+ * \fn template<typename T> template <int Size = 10> void TemplatedClass<T>::templated_method_with_defaulted_non_type_template_parameter()
+ *
+ * A templated method under a templated class with a defaulted non type template parameter.
+ */
+
+/*!
+ * \fn template<char Category = 'A'> void templated_function_with_defaulted_non_type_template_parameter()
+ * \relates <templated_callables.h>
+ *
+ * A templated function with a defaulted non type template parameter.
+ */
+
+/*!
+ * \fn template<typename T> template <int... Dimensions> void TemplatedClass<T>::templated_method_with_non_type_template_parameter_pack()
+ *
+ * A templated method under a templated class with a non type template parameter pack.
+ */
+
+/*!
+ * \fn template<unsigned... Weights> void templated_function_with_non_type_template_parameter_pack()
+ * \relates <templated_callables.h>
+ *
+ * A templated function with a non type template parameter pack.
+ */
+
+/*!
+ * \fn template<typename T> template <auto Predicate> void TemplatedClass<T>::templated_method_with_placeholder_non_type_template_parameter()
+ *
+ * A templated method under a templated class with a placeholder non type template parameter.
+ */
+
+/*!
+ * \fn template<auto Iterator> void templated_function_with_placeholder_non_type_template_parameter()
+ * \relates <templated_callables.h>
+ *
+ * A templated function with a placeholder non type template parameter.
+ */
+
+/*!
+ * \fn template<typename T> template <typename U, template <typename> typename X> void TemplatedClass<T>::templated_method_with_template_template_parameter(X<U>)
+ *
+ * A templated method under a templated class with a non-defaulted template template parameter.
+ */
+
+/*!
+ * \fn template <typename T, template <typename> typename K> void templated_function_with_template_template_parameter(K<T>)
+ * \relates <templated_callables.h>
+ *
+ * A templated function with a non-defaulted template template parameter.
+ */
+
+/*!
+ * \fn template<typename T> template <typename U, int size, template <typename, int> typename Container = std::array> void TemplatedClass<T>::templated_method_with_defaulted_template_template_parameter(Container<U, size>)
+ *
+ * A templated method under a templated class with a defaulted template template parameter.
+ */
+
+/*!
+ * \fn template <typename T, int size, template <typename, int> typename Container = std::array> void templated_function_with_defaulted_template_template_parameter(Container<T, size>)
+ * \relates <templated_callables.h>
+ *
+ * A templated function with a defaulted template template parameter.
+ */
+
+/*!
+ * \fn template<typename T> template <typename U, template <typename> typename... Container> void TemplatedClass<T>::templated_method_with_template_template_parameter_pack(Container<U>...)
+ *
+ * A templated method under a templated class with a template template parameter pack.
+ */
+
+/*!
+ * \fn template <typename T, template <typename> typename... Container> void templated_function_with_template_template_parameter_pack(Container<T>...)
+ * \relates <templated_callables.h>
+ *
+ * A templated function with a template template parameter pack.
+ */
diff --git a/src/qdoc/qdoc/tests/generatedoutput/testdata/templatedcallables/templated_callables.h b/src/qdoc/qdoc/tests/generatedoutput/testdata/templatedcallables/templated_callables.h
new file mode 100644
index 000000000..7a83e444d
--- /dev/null
+++ b/src/qdoc/qdoc/tests/generatedoutput/testdata/templatedcallables/templated_callables.h
@@ -0,0 +1,69 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only#pragma once
+
+#include <array>
+
+template <typename T>
+class TemplatedClass
+{
+public:
+ template <typename U>
+ void templated_method_with_type_template_parameter(U);
+
+ template <typename U = bool>
+ void templated_method_with_defaulted_type_template_parameter(U);
+
+ template <typename... Ts>
+ void templated_method_with_type_template_parameter_pack(Ts...);
+
+ template <int Size>
+ void templated_method_with_non_type_template_parameter();
+
+ template <int Size = 10>
+ void templated_method_with_defaulted_non_type_template_parameter();
+
+ template <int... Dimensions>
+ void templated_method_with_non_type_template_parameter_pack();
+
+ template <auto Predicate>
+ void templated_method_with_placeholder_non_type_template_parameter();
+
+ template <typename U, template <typename> typename X>
+ void templated_method_with_template_template_parameter(X<U>);
+
+ template <typename U, int size, template <typename, int> typename Container = std::array>
+ void templated_method_with_defaulted_template_template_parameter(Container<U, size>);
+
+ template <typename U, template <typename> typename... Container>
+ void templated_method_with_template_template_parameter_pack(Container<U>...);
+};
+
+template <typename T>
+void templated_function_with_type_template_parameter(T);
+
+template <typename T = char>
+void templated_function_with_defaulted_type_template_parameter(T);
+
+template <typename... Ts>
+void templated_function_with_type_template_parameter_pack(Ts...);
+
+template <char Category>
+void templated_function_with_non_type_template_parameter();
+
+template <char Category = 'A'>
+void templated_function_with_defaulted_non_type_template_parameter();
+
+template <unsigned... Weights>
+void templated_function_with_non_type_template_parameter_pack();
+
+template <auto Iterator>
+void templated_function_with_placeholder_non_type_template_parameter();
+
+template <typename T, template <typename> typename K>
+void templated_function_with_template_template_parameter(K<T>);
+
+template <typename T, int size, template <typename, int> typename Container = std::array>
+void templated_function_with_defaulted_template_template_parameter(Container<T, size>);
+
+template <typename T, template <typename> typename... Container>
+void templated_function_with_template_template_parameter_pack(Container<T>...);
diff --git a/src/qdoc/qdoc/tests/generatedoutput/testdata/templatedcallables/templatedcallables.qdocconf b/src/qdoc/qdoc/tests/generatedoutput/testdata/templatedcallables/templatedcallables.qdocconf
new file mode 100644
index 000000000..f7acdcb61
--- /dev/null
+++ b/src/qdoc/qdoc/tests/generatedoutput/testdata/templatedcallables/templatedcallables.qdocconf
@@ -0,0 +1,17 @@
+include(../configs/config.qdocconf)
+project = templatedcallables
+
+headerdirs = .
+sourcedirs = .
+exampledirs = .
+outputformats = WebXML HTML DocBook
+
+WebXML.quotinginformation = true
+WebXML.nosubdirs = true
+WebXML.outputsubdir = templatedcallables
+
+HTML.nosubdirs = true
+HTML.outputsubdir = templatedcallables
+
+DocBook.nosubdirs = true
+DocBook.outputsubdir = templatedcallables
diff --git a/src/qdoc/qdoc/tests/generatedoutput/tst_generatedoutput.cpp b/src/qdoc/qdoc/tests/generatedoutput/tst_generatedoutput.cpp
index d97b0ac5e..d560160cd 100644
--- a/src/qdoc/qdoc/tests/generatedoutput/tst_generatedoutput.cpp
+++ b/src/qdoc/qdoc/tests/generatedoutput/tst_generatedoutput.cpp
@@ -58,6 +58,7 @@ private slots:
void usingDirective();
void properties();
void testTagFile();
+ void templatedCallables();
void testGlobalFunctions();
void proxyPage();
void nonAsciiCharacterInput();
@@ -596,6 +597,16 @@ void tst_generatedOutput::testTagFile()
testAndCompare("testdata/configs/tagfiles.qdocconf", "testtagfile.tags");
}
+void tst_generatedOutput::templatedCallables() {
+ testAndCompare("testdata/templatedcallables/templatedcallables.qdocconf",
+ "templatedcallables/templated-callables-h.html "
+ "templatedcallables/templated-callables-h.xml "
+ "templatedcallables/templated-callables-h.webxml "
+ "templatedcallables/templatedclass.html "
+ "templatedcallables/templatedclass.xml "
+ "templatedcallables/templatedclass.webxml");
+}
+
void tst_generatedOutput::testGlobalFunctions()
{
testAndCompare("testdata/configs/testglobals.qdocconf",