summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuca Di Sera <luca.disera@qt.io>2023-11-21 17:00:12 +0100
committerLuca Di Sera <luca.disera@qt.io>2023-12-05 15:24:19 +0100
commit9caedaa1a79c327aa0dc10bcde9774831b1d47e6 (patch)
treee01007cfaa102f1e371e3c709bd3376a43643fcb
parent1e745d04ff91683d87d296a738221cc0d50841cc (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.h161
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 {};