doxygen / doxygen

Official doxygen git repository
https://www.doxygen.org
GNU General Public License v2.0
5.62k stars 1.27k forks source link

specialized template functions don't show specialization value #10273

Open oumuamua97 opened 1 year ago

oumuamua97 commented 1 year ago

Describe the bug Specialized template functions show in xml with no indication of the specialization value. In the example code, all specializations result in the same output, and are indistinguishable. E.g. the following:

template<>
double Container::estimateWeight<BERRY>(int count)
{
    return count * 0.05L;
}

produces xml that is identical to what's produced for other specialization values, except for the line number information:

      <memberdef kind="function" id="classContainer_1aebbbecda08669ae8f3cf1f0c93e3a71c" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
        <templateparamlist>
        </templateparamlist>
        <type>double</type>
        <definition>double Container::estimateWeight</definition>
        <argsstring>(int count)</argsstring>
        <name>estimateWeight</name>
        <qualifiedname>Container::estimateWeight</qualifiedname>
        <param>
          <type>int</type>
          <declname>count</declname>
        </param>
        <briefdescription>
        </briefdescription>
        <detaileddescription>
        </detaileddescription>
        <inbodydescription>
        </inbodydescription>
        <location file="template_specialization.cpp" line="4" column="1" bodyfile="template_specialization.cpp" bodystart="4" bodyend="7"/>
      </memberdef>

Expected behavior Could the section be made to include the specialization value?

To Reproduce

// template_specialization.h

enum FruitType
{
    BERRY,
    POME,
    DRUPE,
    PEPO
};

class Container
{
public:
    template <FruitType>
    double estimateWeight(int count);
};
// template_specialization.cpp

#include "template_specialization.h"

template<>
double Container::estimateWeight<BERRY>(int count)
{
    return count * 0.05L;
}

template<>
double Container::estimateWeight<POME>(int count)
{
    return count * 0.5L;
}

template<>
double Container::estimateWeight<DRUPE>(int count)
{
    return count * 1.0L;
}

template<>
double Container::estimateWeight<PEPO>(int count)
{
    return count * 5.0L;
}
# doxygen.config

GENERATE_XML = YES
GENERATE_HTML = NO
GENERATE_LATEX = NO

INPUT = template_specialization.h template_specialization.cpp

Output - classContainer.xml:

<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="1.10.0" xml:lang="en-US">
  <compounddef id="classContainer" kind="class" language="C++" prot="public">
    <compoundname>Container</compoundname>
    <sectiondef kind="public-func">
      <memberdef kind="function" id="classContainer_1aa3f3556090eede96d755273ade911447" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
        <templateparamlist>
          <param>
            <type>FruitType</type>
          </param>
        </templateparamlist>
        <type>double</type>
        <definition>double Container::estimateWeight</definition>
        <argsstring>(int count)</argsstring>
        <name>estimateWeight</name>
        <qualifiedname>Container::estimateWeight</qualifiedname>
        <param>
          <type>int</type>
          <declname>count</declname>
        </param>
        <briefdescription>
        </briefdescription>
        <detaileddescription>
        </detaileddescription>
        <inbodydescription>
        </inbodydescription>
        <location file="template_specialization.h" line="13" column="12"/>
      </memberdef>
      <memberdef kind="function" id="classContainer_1aebbbecda08669ae8f3cf1f0c93e3a71c" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
        <templateparamlist>
        </templateparamlist>
        <type>double</type>
        <definition>double Container::estimateWeight</definition>
        <argsstring>(int count)</argsstring>
        <name>estimateWeight</name>
        <qualifiedname>Container::estimateWeight</qualifiedname>
        <param>
          <type>int</type>
          <declname>count</declname>
        </param>
        <briefdescription>
        </briefdescription>
        <detaileddescription>
        </detaileddescription>
        <inbodydescription>
        </inbodydescription>
        <location file="template_specialization.cpp" line="4" column="1" bodyfile="template_specialization.cpp" bodystart="4" bodyend="7"/>
      </memberdef>
      <memberdef kind="function" id="classContainer_1aebbbecda08669ae8f3cf1f0c93e3a71c" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
        <templateparamlist>
        </templateparamlist>
        <type>double</type>
        <definition>double Container::estimateWeight</definition>
        <argsstring>(int count)</argsstring>
        <name>estimateWeight</name>
        <qualifiedname>Container::estimateWeight</qualifiedname>
        <param>
          <type>int</type>
          <declname>count</declname>
        </param>
        <briefdescription>
        </briefdescription>
        <detaileddescription>
        </detaileddescription>
        <inbodydescription>
        </inbodydescription>
        <location file="template_specialization.cpp" line="10" column="1" bodyfile="template_specialization.cpp" bodystart="10" bodyend="13"/>
      </memberdef>
      <memberdef kind="function" id="classContainer_1aebbbecda08669ae8f3cf1f0c93e3a71c" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
        <templateparamlist>
        </templateparamlist>
        <type>double</type>
        <definition>double Container::estimateWeight</definition>
        <argsstring>(int count)</argsstring>
        <name>estimateWeight</name>
        <qualifiedname>Container::estimateWeight</qualifiedname>
        <param>
          <type>int</type>
          <declname>count</declname>
        </param>
        <briefdescription>
        </briefdescription>
        <detaileddescription>
        </detaileddescription>
        <inbodydescription>
        </inbodydescription>
        <location file="template_specialization.cpp" line="16" column="1" bodyfile="template_specialization.cpp" bodystart="16" bodyend="19"/>
      </memberdef>
      <memberdef kind="function" id="classContainer_1aebbbecda08669ae8f3cf1f0c93e3a71c" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
        <templateparamlist>
        </templateparamlist>
        <type>double</type>
        <definition>double Container::estimateWeight</definition>
        <argsstring>(int count)</argsstring>
        <name>estimateWeight</name>
        <qualifiedname>Container::estimateWeight</qualifiedname>
        <param>
          <type>int</type>
          <declname>count</declname>
        </param>
        <briefdescription>
        </briefdescription>
        <detaileddescription>
        </detaileddescription>
        <inbodydescription>
        </inbodydescription>
        <location file="template_specialization.cpp" line="22" column="1" bodyfile="template_specialization.cpp" bodystart="22" bodyend="25"/>
      </memberdef>
    </sectiondef>
    <briefdescription>
    </briefdescription>
    <detaileddescription>
    </detaileddescription>
    <location file="template_specialization.h" line="9" column="1" bodyfile="template_specialization.h" bodystart="10" bodyend="14"/>
    <listofallmembers>
      <member refid="classContainer_1aa3f3556090eede96d755273ade911447" prot="public" virt="non-virtual"><scope>Container</scope><name>estimateWeight</name></member>
      <member refid="classContainer_1aebbbecda08669ae8f3cf1f0c93e3a71c" prot="public" virt="non-virtual"><scope>Container</scope><name>estimateWeight</name></member>
      <member refid="classContainer_1aebbbecda08669ae8f3cf1f0c93e3a71c" prot="public" virt="non-virtual"><scope>Container</scope><name>estimateWeight</name></member>
      <member refid="classContainer_1aebbbecda08669ae8f3cf1f0c93e3a71c" prot="public" virt="non-virtual"><scope>Container</scope><name>estimateWeight</name></member>
      <member refid="classContainer_1aebbbecda08669ae8f3cf1f0c93e3a71c" prot="public" virt="non-virtual"><scope>Container</scope><name>estimateWeight</name></member>
    </listofallmembers>
  </compounddef>
</doxygen>

Version Compiled doxygen from TOT: Commit 09f9ff7b98f296514dbeb4e2312849e1fb8690a9 Author: Dimitri van Heesch [doxygen@gmail.com](mailto:doxygen@gmail.com) Date: Wed Aug 30 21:30:46 2023 +0200 Prevent recursive lockup when instantiating complex recursive templates Problematic file can be found in the open source project folly, file: folly/functional/traits.h

albert-github commented 1 year ago

Thanks for testing it against the latest version from master!

Due to the nature of the problem and the fix of the mentioned commit lit looks a bit that the mentioned commit is the culprit, though this is not the case the problem is already present in the previous commits as well as well as in the released doxygen version 1.9.8.

Similar problems also show in HTML and LaTeX (here I get LaTeX Warning: LabelclassContainer_aebbbecda08669ae8f3cf1f0c93e3a71c' multiply defined.`).

Especially problematic is also that there are now a number of places the have the same id i.e. id="classContainer_1aebbbecda08669ae8f3cf1f0c93e3a71c"