When QDoc parses the source code for a project, it generates a series of internal representations, `Node`s, that are later used to retrieve information about specific elements, compare the user-provided documentation to the parsed code and later produce the output documentation.
When QDoc encounters a friend declaration, it saves it as its own `Node`, under the `Aggregate` `Node` representing the currently parsed object.
Similarly, this is done for other declarations.
This entails that, given a certain friend declaration and an out-of-line definition for it, QDoc will produce two `Node`s representing the same element under different parents.
As the two `Node`s live in different namespaces, albeit they represent the same data, they are internally treated as different elements from a QDoc perspective, which in turn allows documenting both `Node` as if they were a different element without triggering any warning on the part of QDoc.
This duplication should in generally be avoided, and we should instead aim to have a single representation for each unique "element" that QDoc is able to document.
When this will be the case, we will avoid the class of bugs where QDoc allows duplicate documentation to be produced without being able to produce a warning and simplify the internal representation to ensure that a single source of truth can be provided for each documentable element.
To achieve this, QDoc should avoid generating a `Node` when it encounters a friend declaration, as it is expected that a definition for the element will be found out-of-line and will generate a `Node` itself, which will be correctly positioned under a relevant namespace.
The case where the friend declaration is itself a definition, that is, it is an hidden friend, should be treated differently, as there is an expectation that no other declaration or definition will refer to it in other parts of the code-base.
For those cases, QDoc should generate a `Node` for the hidden friend, under some namespace that is different from the one defined by the currently parsed object.
The implementation of this behavior mostly lives in `ClangCodeParser` and it is expected that relatively substantial changes to the sequencing of some of its operations will be required to complete the task.
A similar issue lays with the implementation of QDoc's related-non-members, which are used for friends too.
Related-non-members are `Node`s that are not part of a specific `Aggregate` but are expected to be documented under that `Aggregate` in the output documentation.
The current implementation expects each related-non-member to act as if it was a child a of the `Aggregate`. To achieve this purpose, a series of code-paths are present in the code-base.
In particular, `Aggregate::adoptChild` which is used for the purpose of supporting related-non-members, producing a `Node` that has functionally two parents.
`Aggregate::adoptChild` is further problematic as it later requires specialized code to correctly drop the nodes, as it virtually changes our structure to a graph albeit we treat it as a tree.
Any changes to QDoc `Node` structure might change behavior in other parts of the code-base in unexpected ways, as it will touch the code-parsing phase, the parsing phase, the generation phase, the serialization and deserialization of the index files and the way in which some of the implementation of QDocDatabase works.
There is currently no good infrastructure to ensure that all parts are taken care of correctly during such a change so that careful testing should be exercised during the production of the task.