diff options
author | Luca Di Sera <luca.disera@qt.io> | 2023-11-21 17:00:12 +0100 |
---|---|---|
committer | Luca Di Sera <luca.disera@qt.io> | 2023-12-05 15:24:19 +0100 |
commit | 9caedaa1a79c327aa0dc10bcde9774831b1d47e6 (patch) | |
tree | e01007cfaa102f1e371e3c709bd3376a43643fcb | |
parent | 1e745d04ff91683d87d296a738221cc0d50841cc (diff) |
QDoc: Add 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
declaration, such as taking them into consideration when matching or
allowing the user to document template parameters in a sanity-checked
way, a more granular, albeit very simplified, representation for
template declarations is added to QDoc.
The representation lives in the new header file, under the root
directory for the QDoc binary source files, "template_declaration.h".
The header exports a series of types that can be used to
represent a simplified model of a template declaration, lowered to a
lossy format.
The exported types model is non-strict and aims to be lightweight, as
the representation is expected to be used as an intermediate storage for
Clang-extracted information, which is already validated.
The new representation, while currently unused, is expected to replace
the current "whole-string" representation that QDoc uses for template
declarations in the near future.
Task-number: QTBUG-118080
Task-number: QTBUG-117881
Change-Id: I6520af5ede060bd75f0ecf6b260915c80634a550
Reviewed-by: Topi Reiniƶ <topi.reinio@qt.io>
-rw-r--r-- | src/qdoc/qdoc/src/qdoc/template_declaration.h | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/src/qdoc/qdoc/src/qdoc/template_declaration.h b/src/qdoc/qdoc/src/qdoc/template_declaration.h new file mode 100644 index 000000000..24789db6a --- /dev/null +++ b/src/qdoc/qdoc/src/qdoc/template_declaration.h @@ -0,0 +1,161 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#pragma once + +#include <cstdint> +#include <optional> +#include <string> +#include <vector> + +/* + * Represents a general declaration that has a form that can be + * described by a type, name and initializer triplet, or any such form + * that can be described by zero or more of those same parts. + * + * For example, it can be used to represent a C++ variable declaration + * such as: + * + * std::vector<int> foo = { 1, 2, 3 }; + * + * Where `std::vector<int>` is the type, `foo` is the name and `{ 1, 2, + * 3 }` is the initializer. + * + * Similarly, it can be used to represent a non-type template parameter + * declaration, such as the `foo` parameter in: + * + * template<int foo = 10> + * + * Where `int` is the type, `foo` is the name and `10` is the + * initializer. + * + * An instance can be used to represent less information dense elements + * by setting one or more of the fields as the empty string. + * + * For example, a template type parameter such as `T` in: + * + * template<typename T = int> + * + * Can be represented by an instance that has an empty string as the + * type, `T` as the name and `int` as the initializer. + * + * In general, it can be used to represent any such element that has + * zero or more of the three components, albeit, in QDoc, it is + * specifically intended to be used to represent various C++ + * declarations. + * + * All three fields are lowered stringified version of the original + * declaration, so that the type should be used at the end of a + * pipeline where the semantic property of the represented code are not + * required. + */ +struct ValuedDeclaration +{ + std::string type; + std::string name; + std::string initializer; +}; + +struct RelaxedTemplateParameter; + +struct TemplateDeclarationStorage +{ + std::vector<RelaxedTemplateParameter> parameters; +}; + +/* + * Represents a C++ template parameter. + * + * The model used by this representation is a slighly simplified + * model. + * + * In the model, template parameters are one of: + * + * - A type template parameter. + * - A non type template parameter. + * - A template template parameter. + * + * Furthermore, each parameter can: + * + * - Be a parameter pack. + * - Carry an additional template declaration (as a template template + * parameter would). + * - Have no declared type. + * - Have no declared name. + * - Have no declared initializer. + * + * Due to this simplified model certain incorrect parameters can be + * represented. + * + * For example, it might be possible to represent a parameter pack + * that has a default initializer, a non-type template parameter that + * has no type or a template template parameter that carries no + * template declaration. + * + * The model further elides some of the semantic that might be carried + * by a parameter. + * For example, the model has no specific concept for template + * constraints. + * + * Template parameters can be represented as instances of the type. + * + * For example, a type template parameter `typename T` can be + * represented as the following instance: + * + * RelaxedTemplateParameter{ + * RelaxedTemplateParameter::Kind::TypeTemplateParameter, + * false, + * { + * "", + * "T", + * "" + * }, + * {} + * }; + * + * And a non-type template parameter pack "int... Args" as: + * + * RelaxedTemplateParameter{ + * RelaxedTemplateParameter::Kind::NonTypeTemplateParameter, + * true, + * { + * "int", + * "Args", + * "" + * }, + * {} + * }; + * + * Due to the relaxed constraint and the representable incorrect + * parameters, the type is intended to be used for data that is + * already validated and known to be correct, such as data that is + * extracted from Clang. + */ +struct RelaxedTemplateParameter +{ + enum class Kind : std::uint8_t { + TypeTemplateParameter, + NonTypeTemplateParameter, + TemplateTemplateParameter + }; + + Kind kind; + bool is_parameter_pack; + ValuedDeclaration valued_declaration; + std::optional<TemplateDeclarationStorage> template_declaration; +}; + +/* + * Represents a C++ template declaration as a collection of template + * parameters. + * + * The parameters for the declaration follow the same relaxed rules as + * `RelaxedTemplateParameter` and inherit the possibility of + * representing incorrect declarations. + * + * Due to the relaxed constraint and the representable incorrect + * parameters, the type is intended to be used for data that is + * already validated and known to be correct, such as data that is + * extracted from Clang. + */ +struct RelaxedTemplateDeclaration : TemplateDeclarationStorage {}; |