diff options
author | Luca Di Sera <luca.disera@qt.io> | 2023-11-27 14:08:25 +0100 |
---|---|---|
committer | Luca Di Sera <luca.disera@qt.io> | 2023-12-05 15:24:29 +0100 |
commit | 2891c622c8ba02115e29d4486561d7fa9aba5b00 (patch) | |
tree | f0be100d3bc3727244ed717321f97ba184db8f05 | |
parent | 436affa3ce95df8c5c042de91c4ddf522e0cae20 (diff) |
QDoc: Use a more granular representation for template declarations
When QDoc parses a project, it parses the source code to extract the
user-provided documentation and perform sanity checkings based on the
code itself on it.
When QDoc parses an "\fn" command as part of this process, it tries to
understand, based on its intermediate representation built on the
information extracted from the code-base, which "documentable element"
the "\fn" refers to.
When QDoc performs this "matching" process, it takes into consideration
only a certain amount of information.
For example, no checking is performed over the template declaration of a
callable.
Due to QDoc ignoring template declaration when "matching", certain
elements are not documentable, as they are indistinguishable.
For example, two callables that are overloaded on their specialization
will be treated as a single documentable element by QDoc, so that they
cannot both be referred to when documenting the code-base.
Currently, QDoc extracts template declarations from templated elements
directly from Clang, and stores them whole as a stringified
representation.
This representation allows QDoc to only take into consideration a whole
template declaration, as the representation lacks granularity.
Due to this representation, QDoc does not have, for example, easy access
to the information about single template parameters in a declaration.
This lack of granularity, in turn, prevents QDoc from performing more
complex operations on a template declaration.
For example, the representation would not easily allow QDoc to
understand if a documentation block mentions or not the name of a
template parameter, similar to what is done for callables parameters by
the "\a" command.
Similarly, it would only allow QDoc to perform "matching" on the whole
declaration, which might be different under the current retrieval
process when extracted from the code (where it is extracted from a
declaration) or from an "\fn" command (where it is extracted from a mock
out-of-line definition).
To simplify the implementation of features related to template
declarations, such as taking them into consideration when matching or
allowing the user to document template parameters in a sanity-checked
way, the more granular, albeit very simplified, representation that was
recently added in "template_declaration.h" will now be used for storing
the extracted template declarations.
Previously, QDoc would extract template declarations, where necessary,
by the usage of the mutually recursive free functions `templateDecl` and
`getTemplateParameters` in "clangcodeparser.cpp".
The two functions worked together to extract a string representation of
the whole declaration, which was later stored in a `Node`, the
intermediate representation that QDoc uses for documentable elements.
Those two functions are now removed and replaced by the
`get_template_declaration` free function, in "clangcodeparser.cpp",
which performs a similar process but extracts a template declaration as
a `RelaxedTemplateDeclaration`, a more granular representation for the
same concept.
To support the implementation of `get_template_declaration` and reduce
some code duplication, a series of free functions where added to
"clangcodeparser.cpp".
`get_expression_as_string` now takes care of retrieving a C++ expression
from the original code-base of the project. This is generally necessary
when working with certain elements that can have a default value.
The `get_default_value_initializer_as_string` overload set takes care of
extracting a stringified version of the default argument of a parameter
by dispatching to the correct concrete type some of the element of
Clang's C++ AST, which is inheritance based.
The parts of the code that previously depended on `templateDecl` and
`getTemplateParameters` are now modified to depend on usages of
`getTemplateDeclaration`.
The stored representation of a template declaration as a string in
`Node` was substituted with an optional `RelaxedTemplateDeclaration`,
to be able to store the newly used representations, keeping the general
interface for working with the stored declaration as intact as possible.
Parts of the code-base that interacted with the template declaration
that is stored in a `Node`, such as parts of the various generators that
produce the final output documentation where modified to use the new
representation, generally converting it to its stringified form to
preserve the old behavior.
The new representation is generally equivalent to the previous one with
regards to the way it is shown to the user, even if it allows for more
granularity internally.
Nonetheless, it provides for some small formatting changes.
Previously, template declarations would generally, but not always, lack
a space between the "template" keyword and the following "<" literal.
With the new representation, a the two elements are always divided by a
space.
Furthermore, QDoc now correctly acquires and shows both default argument
initializers for template parameters and information about the parameter
being a pack, while the previous representation elided those
information.
Furthermore, previously QDoc would present a mixed usage of the
"typename" and "class" keyword to present a template declaration.
With the new representation the "typename" keyword will always be
preferred.
The regression files in "tst_generatedOutput" that are touched by the
changes were updated to reflect the new state.
Task-number: QTBUG-118080
Task-number: QTBUG-117881
Change-Id: I0265b5dba81c05f5b145e926be9896a97f7e5446
Reviewed-by: Topi Reiniƶ <topi.reinio@qt.io>
12 files changed, 197 insertions, 98 deletions
diff --git a/src/qdoc/qdoc/src/qdoc/clangcodeparser.cpp b/src/qdoc/qdoc/src/qdoc/clangcodeparser.cpp index e8ed433b2..86d3f1dc8 100644 --- a/src/qdoc/qdoc/src/qdoc/clangcodeparser.cpp +++ b/src/qdoc/qdoc/src/qdoc/clangcodeparser.cpp @@ -38,6 +38,7 @@ #include <llvm/Support/Casting.h> #include "clang/AST/QualTypeNames.h" +#include "template_declaration.h" #include <cstdio> @@ -131,6 +132,108 @@ static std::string get_fully_qualified_type_name(clang::QualType type, const cla ); } +/* + * Retrieves expression as written in the original source code. + * + * declaration_context should be the ASTContext of the declaration + * from which the expression was extracted from. + * + * If the expression contains a leading equal sign it will be removed. + * + * Leading and trailing spaces will be similarly removed from the expression. + */ +static std::string get_expression_as_string(const clang::Expr* expression, const clang::ASTContext& declaration_context) { + QString default_value = QString::fromStdString(clang::Lexer::getSourceText( + clang::CharSourceRange::getTokenRange(expression->getSourceRange()), + declaration_context.getSourceManager(), + declaration_context.getLangOpts() + ).str()); + + if (default_value.startsWith("=")) + default_value.remove(0, 1); + + default_value = default_value.trimmed(); + + return default_value.toStdString(); +} + +/* + * Retrieves the default value of the passed in type template parameter as a string. + * + * The default value of a type template parameter is always a type, + * and its stringified representation will be return as the fully + * qualified version of the type. + * + * If the parameter as no default value the empty string will be returned. + */ +static std::string get_default_value_initializer_as_string(const clang::TemplateTypeParmDecl* parameter) { + return (parameter && parameter->hasDefaultArgument()) ? + get_fully_qualified_type_name(parameter->getDefaultArgument(), parameter->getASTContext()) : + ""; + +} + +/* + * Retrieves the default value of the passed in non-type template parameter as a string. + * + * The default value of a non-type template parameter is an expression + * and its stringified representation will be return as it was written + * in the original code. + * + * If the parameter as no default value the empty string will be returned. + */ +static std::string get_default_value_initializer_as_string(const clang::NonTypeTemplateParmDecl* parameter) { + return (parameter && parameter->hasDefaultArgument()) ? + get_expression_as_string(parameter->getDefaultArgument(), parameter->getASTContext()) : ""; + +} + +/* + * Retrieves the default value of the passed in template template parameter as a string. + * + * The default value of a template template parameter is a template + * name and its stringified representation will be returned as a fully + * qualified version of that name. + * + * If the parameter as no default value the empty string will be returned. + */ +static std::string get_default_value_initializer_as_string(const clang::TemplateTemplateParmDecl* parameter) { + std::string default_value{}; + + if (parameter && parameter->hasDefaultArgument()) { + const clang::TemplateName template_name = parameter->getDefaultArgument().getArgument().getAsTemplate(); + + llvm::raw_string_ostream ss{default_value}; + template_name.print(ss, parameter->getASTContext().getPrintingPolicy(), clang::TemplateName::Qualified::Fully); + } + + return default_value; +} + +/* + * Retrieves the default value of the passed in declaration, based on + * its concrete type, as a string. + * + * If the declaration is a nullptr or the concrete type of the + * declaration is not a supported one, the returned string will be the + * empty string. + */ +static std::string get_default_value_initializer_as_string(const clang::NamedDecl* declaration) { + if (!declaration) return ""; + + if (auto type_template_parameter = llvm::dyn_cast<clang::TemplateTypeParmDecl>(declaration)) + return get_default_value_initializer_as_string(type_template_parameter); + + if (auto non_type_template_parameter = llvm::dyn_cast<clang::NonTypeTemplateParmDecl>(declaration)) + return get_default_value_initializer_as_string(non_type_template_parameter); + + if (auto template_template_parameter = llvm::dyn_cast<clang::TemplateTemplateParmDecl>(declaration)) { + return get_default_value_initializer_as_string(template_template_parameter); + } + + return ""; +} + /*! Call clang_visitChildren on the given cursor with the lambda as a callback T can be any functor that is callable with a CXCursor parameter and returns a CXChildVisitResult @@ -156,61 +259,44 @@ static QString fromCXString(CXString &&string) return ret; } -static QString templateDecl(CXCursor cursor); +/* + * Returns an intermediate representation that models the the given + * template declaration. + */ +static RelaxedTemplateDeclaration get_template_declaration(const clang::TemplateDecl* template_declaration) { + assert(template_declaration); -/*! - Returns a list of template parameters at \a cursor. -*/ -static QStringList getTemplateParameters(CXCursor cursor) -{ - QStringList parameters; - visitChildrenLambda(cursor, [¶meters](CXCursor cur) { - QString name = fromCXString(clang_getCursorSpelling(cur)); - QString type; - - switch (clang_getCursorKind(cur)) { - case CXCursor_TemplateTypeParameter: - type = QStringLiteral("typename"); - break; - case CXCursor_NonTypeTemplateParameter: { - const auto* non_type_template_declaration = - llvm::dyn_cast<clang::NonTypeTemplateParmDecl>(get_cursor_declaration(cur)); - assert(non_type_template_declaration); - - type = QString::fromStdString(get_fully_qualified_type_name( - non_type_template_declaration->getType(), - non_type_template_declaration->getASTContext() - )); - - // Hack: Omit QtPrivate template parameters from public documentation - if (type.startsWith(QLatin1String("QtPrivate"))) - return CXChildVisit_Continue; - break; - } - case CXCursor_TemplateTemplateParameter: - type = templateDecl(cur) + QLatin1String(" class"); - break; - default: - return CXChildVisit_Continue; - } + RelaxedTemplateDeclaration template_declaration_ir{}; - if (!name.isEmpty()) - name.prepend(QLatin1Char(' ')); + auto template_parameters = template_declaration->getTemplateParameters(); + for (auto template_parameter : template_parameters->asArray()) { + auto kind{RelaxedTemplateParameter::Kind::TypeTemplateParameter}; + std::string type{}; - parameters << type + name; - return CXChildVisit_Continue; - }); + if (auto non_type_template_parameter = llvm::dyn_cast<clang::NonTypeTemplateParmDecl>(template_parameter)) { + kind = RelaxedTemplateParameter::Kind::NonTypeTemplateParameter; + type = get_fully_qualified_type_name(non_type_template_parameter->getType(), non_type_template_parameter->getASTContext()); + } - return parameters; -} + auto template_template_parameter = llvm::dyn_cast<clang::TemplateTemplateParmDecl>(template_parameter); + if (template_template_parameter) kind = RelaxedTemplateParameter::Kind::TemplateTemplateParameter; -/*! - Gets the template declaration at specified \a cursor. - */ -static QString templateDecl(CXCursor cursor) -{ - QStringList params = getTemplateParameters(cursor); - return QLatin1String("template <") + params.join(QLatin1String(", ")) + QLatin1Char('>'); + template_declaration_ir.parameters.push_back({ + kind, + template_parameter->isTemplateParameterPack(), + { + type, + template_parameter->getNameAsString(), + get_default_value_initializer_as_string(template_parameter) + }, + (template_template_parameter ? + std::optional<TemplateDeclarationStorage>(TemplateDeclarationStorage{ + get_template_declaration(template_template_parameter).parameters + }) : std::nullopt) + }); + } + + return template_declaration_ir; } /*! @@ -689,7 +775,7 @@ CXChildVisitResult ClangVisitor::visitFnSignature(CXCursor cursor, CXSourceLocat CXChildVisitResult ClangVisitor::visitHeader(CXCursor cursor, CXSourceLocation loc) { auto kind = clang_getCursorKind(cursor); - QString templateString; + switch (kind) { case CXCursor_TypeAliasTemplateDecl: case CXCursor_TypeAliasDecl: { @@ -700,15 +786,17 @@ CXChildVisitResult ClangVisitor::visitHeader(CXCursor cursor, CXSourceLocation l const QLatin1String usingString("using "); qsizetype usingPos = typeAlias[0].indexOf(usingString); if (usingPos != -1) { - if (kind == CXCursor_TypeAliasTemplateDecl) - templateString = typeAlias[0].left(usingPos).trimmed(); typeAlias[0].remove(0, usingPos + usingString.size()); typeAlias[0] = typeAlias[0].split(QLatin1Char(' ')).first(); typeAlias[1] = typeAlias[1].trimmed(); auto *ta = new TypeAliasNode(parent_, typeAlias[0], typeAlias[1]); ta->setAccess(fromCX_CXXAccessSpecifier(clang_getCXXAccessSpecifier(cursor))); ta->setLocation(fromCXSourceLocation(clang_getCursorLocation(cursor))); - ta->setTemplateDecl(templateString); + + if (kind == CXCursor_TypeAliasTemplateDecl) { + auto template_decl = llvm::dyn_cast<clang::TemplateDecl>(get_cursor_declaration(cursor)); + ta->setTemplateDecl(get_template_declaration(template_decl)); + } } } return CXChildVisit_Continue; @@ -719,7 +807,6 @@ CXChildVisitResult ClangVisitor::visitHeader(CXCursor cursor, CXSourceLocation l return CXChildVisit_Continue; Q_FALLTHROUGH(); case CXCursor_ClassTemplate: - templateString = templateDecl(cursor); Q_FALLTHROUGH(); case CXCursor_ClassDecl: { if (!clang_isCursorDefinition(cursor)) @@ -748,8 +835,10 @@ CXChildVisitResult ClangVisitor::visitHeader(CXCursor cursor, CXSourceLocation l classe->setAccess(fromCX_CXXAccessSpecifier(clang_getCXXAccessSpecifier(cursor))); classe->setLocation(fromCXSourceLocation(clang_getCursorLocation(cursor))); - if (kind == CXCursor_ClassTemplate) - classe->setTemplateDecl(templateString); + if (kind == CXCursor_ClassTemplate) { + auto template_declaration = llvm::dyn_cast<clang::TemplateDecl>(get_cursor_declaration(cursor)); + classe->setTemplateDecl(get_template_declaration(template_declaration)); + } QScopedValueRollback<Aggregate *> setParent(parent_, classe); return visitChildren(cursor); @@ -787,7 +876,6 @@ CXChildVisitResult ClangVisitor::visitHeader(CXCursor cursor, CXSourceLocation l return visitChildren(cursor); } case CXCursor_FunctionTemplate: - templateString = templateDecl(cursor); Q_FALLTHROUGH(); case CXCursor_FunctionDecl: case CXCursor_CXXMethod: @@ -816,8 +904,14 @@ CXChildVisitResult ClangVisitor::visitHeader(CXCursor cursor, CXSourceLocation l } } } + processFunction(fn, cursor); - fn->setTemplateDecl(templateString); + + if (kind == CXCursor_FunctionTemplate) { + auto template_declaration = get_cursor_declaration(cursor)->getAsFunction()->getDescribedFunctionTemplate(); + fn->setTemplateDecl(get_template_declaration(template_declaration)); + } + return CXChildVisit_Continue; } #if CINDEX_VERSION >= 36 diff --git a/src/qdoc/qdoc/src/qdoc/cppcodemarker.cpp b/src/qdoc/qdoc/src/qdoc/cppcodemarker.cpp index 78cde1b0e..4ef03986b 100644 --- a/src/qdoc/qdoc/src/qdoc/cppcodemarker.cpp +++ b/src/qdoc/qdoc/src/qdoc/cppcodemarker.cpp @@ -96,9 +96,9 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node, const Node * /* relati case Node::Function: func = (const FunctionNode *)node; if (style == Section::Details) { - const QString &templateDecl = node->templateDecl(); - if (!templateDecl.isEmpty()) - synopsis = templateDecl + QLatin1Char(' '); + auto templateDecl = node->templateDecl(); + if (templateDecl) + synopsis = (*templateDecl).to_qstring() + QLatin1Char(' '); } if (style != Section::AllMembers && !func->returnType().isEmpty()) synopsis += typified(func->returnType(), true); @@ -184,9 +184,9 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node, const Node * /* relati break; case Node::TypeAlias: if (style == Section::Details) { - const QString &templateDecl = node->templateDecl(); - if (!templateDecl.isEmpty()) - synopsis += templateDecl + QLatin1Char(' '); + auto templateDecl = node->templateDecl(); + if (templateDecl) + synopsis += (*templateDecl).to_qstring() + QLatin1Char(' '); } synopsis += name; break; diff --git a/src/qdoc/qdoc/src/qdoc/docbookgenerator.cpp b/src/qdoc/qdoc/src/qdoc/docbookgenerator.cpp index b7d321d9b..c4d875554 100644 --- a/src/qdoc/qdoc/src/qdoc/docbookgenerator.cpp +++ b/src/qdoc/qdoc/src/qdoc/docbookgenerator.cpp @@ -3003,9 +3003,11 @@ void DocBookGenerator::generateCppReferencePage(Node *node) title = rawTitle + " Namespace"; } else if (aggregate->isClass()) { rawTitle = aggregate->plainName(); - QString templateDecl = node->templateDecl(); - if (!templateDecl.isEmpty()) - fullTitle = QString("%1 %2 ").arg(templateDecl, aggregate->typeWord(false)); + + auto templateDecl = node->templateDecl(); + if (templateDecl) + fullTitle = QString("%1 %2 ").arg((*templateDecl).to_qstring(), aggregate->typeWord(false)); + fullTitle += aggregate->plainFullName(); title = rawTitle + QLatin1Char(' ') + aggregate->typeWord(true); } else if (aggregate->isHeader()) { @@ -3850,9 +3852,9 @@ void DocBookGenerator::generateSynopsis(const Node *node, const Node *relative, } break; case Node::TypeAlias: { if (style == Section::Details) { - const QString& templateDecl = node->templateDecl(); - if (!templateDecl.isEmpty()) - m_writer->writeCharacters(templateDecl + QLatin1Char(' ')); + auto templateDecl = node->templateDecl(); + if (templateDecl) + m_writer->writeCharacters((*templateDecl).to_qstring() + QLatin1Char(' ')); } m_writer->writeCharacters(namePrefix); generateSynopsisName(node, relative, generateNameLink); diff --git a/src/qdoc/qdoc/src/qdoc/functionnode.cpp b/src/qdoc/qdoc/src/qdoc/functionnode.cpp index 9f77f9f06..2e6a81edc 100644 --- a/src/qdoc/qdoc/src/qdoc/functionnode.cpp +++ b/src/qdoc/qdoc/src/qdoc/functionnode.cpp @@ -427,8 +427,8 @@ QString FunctionNode::signature(Node::SignatureOptions options) const { QStringList elements; - if (options & Node::SignatureTemplateParams) - elements << templateDecl(); + if (options & Node::SignatureTemplateParams && templateDecl()) + elements << (*templateDecl()).to_qstring(); if (options & Node::SignatureReturnType) elements << m_returnType; elements.removeAll(QString()); diff --git a/src/qdoc/qdoc/src/qdoc/htmlgenerator.cpp b/src/qdoc/qdoc/src/qdoc/htmlgenerator.cpp index e6e1db957..76ac1271e 100644 --- a/src/qdoc/qdoc/src/qdoc/htmlgenerator.cpp +++ b/src/qdoc/qdoc/src/qdoc/htmlgenerator.cpp @@ -1079,7 +1079,7 @@ void HtmlGenerator::generateCppReferencePage(Aggregate *aggregate, CodeMarker *m Sections sections(aggregate); QString word = aggregate->typeWord(true); - QString templateDecl = aggregate->templateDecl(); + auto templateDecl = aggregate->templateDecl(); if (aggregate->isNamespace()) { rawTitle = aggregate->plainName(); fullTitle = aggregate->plainFullName(); @@ -1100,10 +1100,10 @@ void HtmlGenerator::generateCppReferencePage(Aggregate *aggregate, CodeMarker *m } Text subtitleText; - if (rawTitle != fullTitle || !templateDecl.isEmpty()) { + if (rawTitle != fullTitle || templateDecl) { if (aggregate->isClassNode()) { - if (!templateDecl.isEmpty()) - subtitleText << templateDecl + QLatin1Char(' '); + if (templateDecl) + subtitleText << (*templateDecl).to_qstring() + QLatin1Char(' '); subtitleText << aggregate->typeWord(false) + QLatin1Char(' '); const QStringList ancestors = fullTitle.split(QLatin1String("::")); for (const auto &a : ancestors) { diff --git a/src/qdoc/qdoc/src/qdoc/node.h b/src/qdoc/qdoc/src/qdoc/node.h index 65b16c141..65701f64c 100644 --- a/src/qdoc/qdoc/src/qdoc/node.h +++ b/src/qdoc/qdoc/src/qdoc/node.h @@ -11,12 +11,15 @@ #include "importrec.h" #include "parameters.h" #include "relatedclass.h" +#include "template_declaration.h" #include <QtCore/qdir.h> #include <QtCore/qlist.h> #include <QtCore/qmap.h> #include <QtCore/qstringlist.h> +#include <optional> + QT_BEGIN_NAMESPACE class Aggregate; @@ -207,7 +210,7 @@ public: void setSince(const QString &since); void setPhysicalModuleName(const QString &name) { m_physicalModuleName = name; } void setUrl(const QString &url) { m_url = url; } - void setTemplateDecl(const QString &t) { m_templateDecl = t; } + void setTemplateDecl(std::optional<RelaxedTemplateDeclaration> t) { m_templateDecl = t; } void setReconstitutedBrief(const QString &t) { m_reconstitutedBrief = t; } void setParent(Aggregate *n) { m_parent = n; } void setIndexNodeFlag(bool isIndexNode = true) { m_indexNodeFlag = isIndexNode; } @@ -274,7 +277,7 @@ public: [[nodiscard]] ThreadSafeness threadSafeness() const; [[nodiscard]] ThreadSafeness inheritedThreadSafeness() const; [[nodiscard]] QString since() const { return m_since; } - [[nodiscard]] const QString &templateDecl() const { return m_templateDecl; } + [[nodiscard]] const std::optional<RelaxedTemplateDeclaration>& templateDecl() const { return m_templateDecl; } [[nodiscard]] const QString &reconstitutedBrief() const { return m_reconstitutedBrief; } [[nodiscard]] bool isSharingComment() const { return (m_sharedCommentNode != nullptr); } @@ -331,7 +334,7 @@ private: QString m_physicalModuleName {}; QString m_url {}; QString m_since {}; - QString m_templateDecl {}; + std::optional<RelaxedTemplateDeclaration> m_templateDecl{std::nullopt}; QString m_reconstitutedBrief {}; QString m_outSubDir {}; QString m_deprecatedSince {}; diff --git a/src/qdoc/qdoc/tests/generatedoutput/expected_output/proxypage-docbook/stdpair-proxypage-proxy.xml b/src/qdoc/qdoc/tests/generatedoutput/expected_output/proxypage-docbook/stdpair-proxypage-proxy.xml index 7dbbc54c1..5476d7a21 100644 --- a/src/qdoc/qdoc/tests/generatedoutput/expected_output/proxypage-docbook/stdpair-proxypage-proxy.xml +++ b/src/qdoc/qdoc/tests/generatedoutput/expected_output/proxypage-docbook/stdpair-proxypage-proxy.xml @@ -10,7 +10,7 @@ <db:section xml:id="type-documentation"> <db:title>Type Documentation</db:title> <db:section xml:id="StdPair-typedef"> -<db:title>[alias] template <class T1, class T2> StdPair</db:title> +<db:title>[alias] template <typename T1, typename T2> StdPair</db:title> </db:section> </db:section> </db:article> diff --git a/src/qdoc/qdoc/tests/generatedoutput/expected_output/proxypage/stdpair-proxypage-proxy.html b/src/qdoc/qdoc/tests/generatedoutput/expected_output/proxypage/stdpair-proxypage-proxy.html index e91f28721..25241ddcb 100644 --- a/src/qdoc/qdoc/tests/generatedoutput/expected_output/proxypage/stdpair-proxypage-proxy.html +++ b/src/qdoc/qdoc/tests/generatedoutput/expected_output/proxypage/stdpair-proxypage-proxy.html @@ -13,7 +13,7 @@ <div class="types"> <h2>Type Documentation</h2> <!-- $$$StdPair --> -<h3 class="fn" translate="no" id="StdPair-typedef"><code class="details extra" translate="no">[alias]</code> template <class T1, class T2> <span class="name">StdPair</span></h3> +<h3 class="fn" translate="no" id="StdPair-typedef"><code class="details extra" translate="no">[alias]</code> template <typename T1, typename T2> <span class="name">StdPair</span></h3> <!-- @@@StdPair --> </div> </body> diff --git a/src/qdoc/qdoc/tests/generatedoutput/expected_output/template/baz.html b/src/qdoc/qdoc/tests/generatedoutput/expected_output/template/baz.html index 216a7c191..eb939cec5 100644 --- a/src/qdoc/qdoc/tests/generatedoutput/expected_output/template/baz.html +++ b/src/qdoc/qdoc/tests/generatedoutput/expected_output/template/baz.html @@ -18,7 +18,7 @@ </div> <div class="sidebar-content" id="sidebar-content"></div></div> <h1 class="title" translate="no">Baz Struct</h1> -<span class="small-subtitle" translate="no">template <template <typename> class X, typename Y> struct Baz</span> +<span class="small-subtitle" translate="no">template <template <typename> typename X, typename Y> struct Baz</span> <!-- $$$Baz-brief --> <p>Class template template. <a href="#details">More...</a></p> <!-- @@@Baz --> diff --git a/src/qdoc/qdoc/tests/generatedoutput/expected_output/template/testqdoc-test.html b/src/qdoc/qdoc/tests/generatedoutput/expected_output/template/testqdoc-test.html index 1794b2d9a..ab6ee6977 100644 --- a/src/qdoc/qdoc/tests/generatedoutput/expected_output/template/testqdoc-test.html +++ b/src/qdoc/qdoc/tests/generatedoutput/expected_output/template/testqdoc-test.html @@ -90,7 +90,7 @@ target_link_libraries(mytarget PRIVATE Qt6::QDocTest)</td></tr> <p>A typedef.</p> <!-- @@@SomeType --> <!-- $$$Specialized --> -<h3 class="fn" translate="no" id="Specialized-typedef"><code class="details extra" translate="no">[alias]</code> template<typename T> Test::<span class="name">Specialized</span></h3> +<h3 class="fn" translate="no" id="Specialized-typedef"><code class="details extra" translate="no">[alias]</code> template <typename T> Test::<span class="name">Specialized</span></h3> <!-- @@@Specialized --> </div> <div class="func"> 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 index f07956b11..7eac6608b 100644 --- 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 @@ -37,15 +37,15 @@ <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 <char Category> <span class="type">void</span> <span class="name">templated_function_with_defaulted_non_type_template_parameter</span>()</h3> +<h3 class="fn" translate="no" id="templated_function_with_defaulted_non_type_template_parameter">template <char Category = 'A'> <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 <typename T, int size, template <typename, int> class Container> <span class="type">void</span> <span class="name">templated_function_with_defaulted_template_template_parameter</span>(<span class="type">Container</span><<span class="type">T</span>, <span class="type">size</span>>)</h3> +<h3 class="fn" translate="no" id="templated_function_with_defaulted_template_template_parameter">template <typename T, int size, template <typename, int > typename Container = std::array> <span class="type">void</span> <span class="name">templated_function_with_defaulted_template_template_parameter</span>(<span class="type">Container</span><<span class="type">T</span>, <span class="type">size</span>>)</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 <typename T> <span class="type">void</span> <span class="name">templated_function_with_defaulted_type_template_parameter</span>(<span class="type">T</span>)</h3> +<h3 class="fn" translate="no" id="templated_function_with_defaulted_type_template_parameter">template <typename T = char> <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 --> @@ -53,7 +53,7 @@ <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 <unsigned int Weights> <span class="type">void</span> <span class="name">templated_function_with_non_type_template_parameter_pack</span>()</h3> +<h3 class="fn" translate="no" id="templated_function_with_non_type_template_parameter_pack">template <unsigned int... Weights> <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 --> @@ -61,11 +61,11 @@ <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 <typename T, template <typename> class K> <span class="type">void</span> <span class="name">templated_function_with_template_template_parameter</span>(<span class="type">K</span><<span class="type">T</span>>)</h3> +<h3 class="fn" translate="no" id="templated_function_with_template_template_parameter">template <typename T, template <typename> typename K> <span class="type">void</span> <span class="name">templated_function_with_template_template_parameter</span>(<span class="type">K</span><<span class="type">T</span>>)</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 <typename T, template <typename> class Container> <span class="type">void</span> <span class="name">templated_function_with_template_template_parameter_pack</span>(<span class="type">Container</span><<span class="type">T</span>>...)</h3> +<h3 class="fn" translate="no" id="templated_function_with_template_template_parameter_pack">template <typename T, template <typename> typename... Container> <span class="type">void</span> <span class="name">templated_function_with_template_template_parameter_pack</span>(<span class="type">Container</span><<span class="type">T</span>>...)</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 --> @@ -73,7 +73,7 @@ <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 <typename Ts> <span class="type">void</span> <span class="name">templated_function_with_type_template_parameter_pack</span>(<span class="type">Ts</span>...)</h3> +<h3 class="fn" translate="no" id="templated_function_with_type_template_parameter_pack">template <typename... Ts> <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> diff --git a/src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templatedclass.html b/src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templatedclass.html index bf8e84012..fa50411a8 100644 --- a/src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templatedclass.html +++ b/src/qdoc/qdoc/tests/generatedoutput/expected_output/templatedcallables/templatedclass.html @@ -46,15 +46,15 @@ <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 <int Size> <span class="type">void</span> TemplatedClass::<span class="name">templated_method_with_defaulted_non_type_template_parameter</span>()</h3> +<h3 class="fn" translate="no" id="templated_method_with_defaulted_non_type_template_parameter">template <int Size = 10> <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 <typename U, int size, template <typename, int> class Container> <span class="type">void</span> TemplatedClass::<span class="name">templated_method_with_defaulted_template_template_parameter</span>(<span class="type">Container</span><<span class="type">U</span>, <span class="type">size</span>>)</h3> +<h3 class="fn" translate="no" id="templated_method_with_defaulted_template_template_parameter">template <typename U, int size, template <typename, int > typename Container = std::array> <span class="type">void</span> TemplatedClass::<span class="name">templated_method_with_defaulted_template_template_parameter</span>(<span class="type">Container</span><<span class="type">U</span>, <span class="type">size</span>>)</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 <typename U> <span class="type">void</span> TemplatedClass::<span class="name">templated_method_with_defaulted_type_template_parameter</span>(<span class="type">U</span>)</h3> +<h3 class="fn" translate="no" id="templated_method_with_defaulted_type_template_parameter">template <typename U = bool> <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 --> @@ -62,7 +62,7 @@ <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 <int Dimensions> <span class="type">void</span> TemplatedClass::<span class="name">templated_method_with_non_type_template_parameter_pack</span>()</h3> +<h3 class="fn" translate="no" id="templated_method_with_non_type_template_parameter_pack">template <int... Dimensions> <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 --> @@ -70,11 +70,11 @@ <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 <typename U, template <typename> class X> <span class="type">void</span> TemplatedClass::<span class="name">templated_method_with_template_template_parameter</span>(<span class="type">X</span><<span class="type">U</span>>)</h3> +<h3 class="fn" translate="no" id="templated_method_with_template_template_parameter">template <typename U, template <typename> typename X> <span class="type">void</span> TemplatedClass::<span class="name">templated_method_with_template_template_parameter</span>(<span class="type">X</span><<span class="type">U</span>>)</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 <typename U, template <typename> class Container> <span class="type">void</span> TemplatedClass::<span class="name">templated_method_with_template_template_parameter_pack</span>(<span class="type">Container</span><<span class="type">U</span>>...)</h3> +<h3 class="fn" translate="no" id="templated_method_with_template_template_parameter_pack">template <typename U, template <typename> typename... Container> <span class="type">void</span> TemplatedClass::<span class="name">templated_method_with_template_template_parameter_pack</span>(<span class="type">Container</span><<span class="type">U</span>>...)</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 --> @@ -82,7 +82,7 @@ <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 <typename Ts> <span class="type">void</span> TemplatedClass::<span class="name">templated_method_with_type_template_parameter_pack</span>(<span class="type">Ts</span>...)</h3> +<h3 class="fn" translate="no" id="templated_method_with_type_template_parameter_pack">template <typename... Ts> <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> |