Skip to content

Incorrect parsing to xml of c++11 constructs in methods and functions #10708

@SimonMarynissen

Description

@SimonMarynissen

Describe the bug
The xml output is not complete/incorrect when using 'modern' c++ (c++11 or later, more than a decade old). This issue is actually a few issue together, I can split this issue in different issues if you want me to.
When parsing class methods, not all information is properly represented in xml (this xml is used by tools like sphinx-breathe to generate documentation), for example for the following snippet of code:

#ifndef INCLUDE_GUARD
#define INCLUDE_GUARD

#include <type_traits>

/// @brief Some class
class A
{
public:
	/// @brief Does stuff
	[[nodiscard]] constexpr int do_stuff() noexcept(std::is_nothrow_move_assignable_v<A>);
	
	/// @brief Does stuff
	[[nodiscard]] constexpr auto do_stuff2() noexcept(std::is_nothrow_move_assignable_v<A>) -> int;
};

#endif

When it gets parsed to xml, we get

<memberdef kind="function" id="class_a_1ac5350de77c7e927b4bafa27a899743a8" prot="public" static="no" constexpr="yes" const="no" explicit="no" inline="no" noexcept="yes" virt="non-virtual">
    <type>constexpr int</type>
    <definition>constexpr int A::do_stuff</definition>
    <argsstring>() noexcept(std::is_nothrow_move_assignable_v&lt; A &gt;)</argsstring>
    <name>do_stuff</name>
    <qualifiedname>A::do_stuff</qualifiedname>
    <briefdescription>
        <para>Does stuff. </para>
    </briefdescription>
    <detaileddescription>
    </detaileddescription>
    <inbodydescription>
    </inbodydescription>
    <location file="header.hpp" line="11" column="16"/>
</memberdef>
<memberdef kind="function" id="class_a_1aa0ac26ebde08a69be4382f29077bd5d4" prot="public" static="no" constexpr="yes" const="no" explicit="no" inline="no" noexcept="yes" virt="non-virtual">
    <type>constexpr auto</type>
    <definition>constexpr auto A::do_stuff2</definition>
    <argsstring>() noexcept(std::is_nothrow_move_assignable_v&lt; A &gt;) -&gt; int</argsstring>
    <name>do_stuff2</name>
    <qualifiedname>A::do_stuff2</qualifiedname>
    <briefdescription>
        <para>Does stuff. </para>
    </briefdescription>
    <detaileddescription>
    </detaileddescription>
    <inbodydescription>
    </inbodydescription>
    <location file="header.hpp" line="14" column="17"/>
</memberdef>

Expected behavior
Describe what you would have expected or think is correct.

  • The type should be int in both functions, since constexpr is not part of the type here, but says something about the function itself. The constexprness is already part of the memberdef tag, so why repeat the information.
  • The argsstring should be () in both functions. The keyword noexcept is not something that belongs to the argument list, but is a property of the function. Moreover, two identical functions except for the noexcept specifier are two different overloads. Perhaps, the noexcept should be extended to be not only no or yes, but can be something like
    noexcept="std::is_nothrow_move_assignable_v&lt; A &gt;"
  • The definition should include the noexcept and trailing return type if it used (see the above points)
  • Similarly, some attributes such as [[nodiscard]]) could be documented (at least make it possible)

To Reproduce
doxygen_issue.zip

Version
Windows 10 64 bit
doxygen 1.10.0 with libclang 18.0.0 (normally installed doxygen with .dll replaced, but it also does this with normal doxygen)

Additional
If I am given some direction on how to solve it, I could make a pull request for it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions