summaryrefslogtreecommitdiff
path: root/src/qdoc/clangcodeparser.cpp
Commit message (Collapse)AuthorAgeFilesLines
* QDoc: Move QDoc source files under a further "qdoc" directoryLuca Di Sera2023-04-121-1783/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QDoc development under the "qttools" repository is currently performed under the "src/qdoc" directory, which contains all source files and directories relevant to QDoc as direct children. Due to a slow restructuring of how QDoc works, what its dependencies are and certain possible architectural changes, the infrastructure that is expected to be required for the development of QDoc might increase. Some of that infrastructure, which might require some custom effort, is expected to be developed as "independent" "library-like" sub-projects, which QDoc depends on. Albeit developed "independently", such infrastructure would be developed specifically for QDoc and thus should live "adjacent" to it. To allow such a structure a new "qdoc" directory was added under the "src/qdoc" directory. All source files and directory that were previously children of the "src/qdoc" directory were moved under the new "qdoc" directory. This preserves the space for QDoc-related elements and the relative project structure while allowing some space for "adjacent" projects that are intended for QDoc specifically. To support the change, a new "CMakeLists.txt" file was introduced under "src/qdoc", which dispatches to the "CMakeLists.txt" file in the new "src/qdoc/qdoc" directory. QDoc is only built when certain dependencies are found. This is supported through the use of Qt features at the CMake level. The "CMakeLists.txt" file in "src", thus dispatched to the "src/qdoc" directory only when the required features were found. As "independent", "library-like", entities might not have the same requirements as QDoc, the "CMakeLists.txt" file in "src" was modified to always dispatch to the "src/qdoc" directory while the features-check was moved to the new "CMakeLists.txt" files in "src/qdoc", so as to allow non-QDoc but QDoc-specific project to have an independent configuration for building. Certain test projects in "test/auto/qdoc/" depends on QDoc-specific source-files to generate their CMake targets. Those dependencies were generally specified as relative paths. The additional level in the directory structure invalidated the paths and, hence, the relevant "CMakeLists.txt" files for those projects were modified to correctly refer to the new directory structure. Change-Id: I50c7106614428753544eaba5091e1e44d48fd31d Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Simplify struct FindPredicate::operator()Paul Wicking2023-03-301-8/+1
| | | | | | | | | | | Recent changes removed the enum value SearchType::Module from the FindPredicate struct's member enum. This made the switch in the struct's operator() on `type_` redundant, as the two remaining cases both result in the same behavior. Remove the switch as it isn't needed anymore. Change-Id: Ib2a15de7d4aa9588943a6babb497ec2b970a6290 Reviewed-by: Luca Di Sera <luca.disera@qt.io>
* QDoc: Remove unused enum value and case from ClangCodeParserPaul Wicking2023-03-301-4/+1
| | | | | | | | | A recent change made the enum value ClangCodeParser::buildPCH::FindPredicate::SearchType::Private unused. Remove the enum value and the case that considers it. Change-Id: If3f4379bdad2339e873e347e422df35871629d38 Reviewed-by: Luca Di Sera <luca.disera@qt.io>
* QDoc: Remove dead code in ClangCodeParserPaul Wicking2023-03-271-7/+1
| | | | | | | | | | ClangCodeParser::buildPCH included a local variable, privateHeaderDir, which was written to in a loop over the parser's includeDaths private member, but never read. This patch removes the local variable and loop from said method, as it is effectively dead code. Change-Id: Ifae97e0e31074bb4e5d97a427f9392b2526f2f37 Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Remove nesting level from `ClangCodeParser::buildPCH`Luca Di Sera2023-03-271-109/+110
| | | | | | | | | | | | | | | | | | | `ClangCodeParser`, the class responsible for parsing Cpp source files during a QDoc run, uses a PCH to speed up compilation when reading the above mentioned source file. A PCH file is built in `ClangCodeParser::buildPCH`. To avoid redoing the same work more than one time if it is unnecessary, `buildPCH` branches on certain conditions and does nothing if those conditions are not met. To make the code easier to read, move the code that performs the PCH building operation to the top level of the method body, instead of branching, and use early returns when the conditions are not satisfied. Change-Id: I95b07a12bc1723ea7bdaee41367483a61dcb5609 Reviewed-by: Topi Reiniö <topi.reinio@qt.io> Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* QDoc: Remove `CppCodeParser` from the `CodeParser` hierarchyLuca Di Sera2023-03-221-12/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QDoc extracts the user-provided documentation from which its output is generated from a variety of input source file based on a project configuration. Those input source file can be of a variety of formats, as long as QDoc currently supports them. When parsing those files, QDoc extracts format specific information, such as information about the available elements in a C++ translation unit, and all the QDoc language comment-block that form the actual documentation. The format specific elements that are extracted are lowered into an internal representation, the `Node` hierarchy, that QDoc later uses to perform sanity checks on the user-provided documentation or to automatically generate certain documentation. The QDoc comment-blocks are generally processed in place, and they, too, are converted into an internal representation, partly filling a `Node` data partly filling a `Doc` instance, and used during later stages to generate the final output. It performs this process through the `CodeParser` hierarchy. The base `CodeParser` class provides an interface to parse certain source file based on their extension. Child classes of `CodeParser` implements the actual parsing based on the format that they support. `CppCodeParser`, a direct child of `CodeParser`, implements the semantic for topic and meta commands in a comment block. That is, it gives meaning to commands such as `\fn` and `\example`. `ClangCodeParser`, a direct child of `CppCodeParser` and indirect child of `CodeParser`, implements the logic to extract information from C++ source code. `PureDocParser`, a direct child of `CppCodeParser` and an indirect child of `CodeParser`, implements the logic to extract QDoc comment-blocks from a ".qdoc" file. Finally, `QmlCodeParser`, a direct child of `CodeParser`, implements the logic to extract information from QML source files. Both `ClangCodeParser` and `PureDocParser`, but not `QmlCodeParser`, depends on `CppCodeParser`. That is, as they process the found QDoc comment-block in-place during their parsing, they use `CppCodeParser` to perform this processing. Indeed, `CppCodeParser` is never itself instanciated, and is only intended to provide the shared logic for `ClangCodeParser` and `PureDocParser`. At the same, since `CppCodeParser` purpose is not to actually parse any source file, it doesn't respect, meaningfully, the interface for `CodeParser`, mostly providing stub implementation for its pure virtual methods to satisfy the compiler. Due to recent, purposefully made, changes, `CppCodeParser` does not depend, mostly, on any internal-only state of `CodeParser`, while `ClangCodeParser` and `PureDocParser` do not depend on any internal-only state of `CppCodeParser`, instead depending only on access to some of its methods. Hence, `CppCodeParser`, which does not respect the `CodeParser` interface meaningfully, can be removed from the hierarchy, simplifying it and reducing the implicit state and interface of the other members, additionally moving the codebase forward in the intention of removing the `CodeParser` interface and some of the shared-mutable state that QDoc depends on. Thus, `CppCodeParser` does not inherit anymore from `CodeParser`. As a consequence, `ClangCodeParser` and `PureDocParser` now inherit directly from `CodeParser`, flattening the hierarchy depth to one. Certain pure virtual methods that were provided directly or indirectly by `CppCodeParser` are now implemented directly in `ClangCodeParser` and `PureDocParser` to satisfy the `CodeParser` interface. In particular, `ClangCodeParser` now implements an empty `terminateParser`, as before the `terminateParser` implementation only referred back to `CppCodeParser::terminateParser`. Similarly, `ClangCodeParser::initializeParser` does not refer back to `CppCodeParser::initializeParser` anymore. `PureDocParser` now implements empty `initializeParser` and `language` methods, as, while required by the `CodeParser` inheritance, are completely meaningless in the scope of the class. The methods that `CppCodeParser` inherited from `CodeParser` are thus removed. That is, `CppCodeParser::initializeParser`, `CppCodeParser::terminateParser`, `CppCodeParser::language` and `CppCodeParser::sourceFileNameFilter` are directly deleted. `CodeParser` objects are built once and registered into a static list owned by `CodeParser`. Their lifetime is then managed by the `initialize`/`terminate` methods of `CodeParser`, manually. As `CppCodeParser` does not respect this manual management anymore, the processing performed in `initializeParser` was moved to its constructor and the processing performed in `terminateParser` was moved to its destructor. In doing so a declaration for the destructor was added to "cppcodeparser.h" and an implementation of it was added to "cppcodeparser.cpp", replacing the `terminateParser` implementation. Similarly, the defaulted constructor for `CppCodeParser` was removed in favor of a custom one and its implementation replaces the implementation for `initializeParser`. The implementation for `CppCodeParser` made use of the `m_qdb`, a pointer to the `QDocDatabase` singleton, which keeps a certain amount of state that is necessary during parsing, instance-member provided by the `CodeParser` class. Due to the changes in the inheritance hierarchy, those usages were modified to obtain an instance of the database directly in their scope. In particular, `CppCodeParser::parseOtherFuncArg`, `CppCodeParser::parseMacroArg`, `CppCodeParser::processTopicArgs`, `CppCodeParser::processQmlProperties`, `CppCodeParser::processMetaCommand` and `CppCodeParser::processTopicCommand` were modified as such. `CppCodeParser` made use of certain static methods of `CodeParser`. Usages of those methods were modified to directly refer to the `CodeParser` namespace as they are not implicitly available in the relevant scopes anymore. In particular, `CppCodeParser::processTopicArgs`, which referenced `CodeParser::parserForLanguage` and `processTopicCommands`/`processMetaCommand`, which referenced `CodeParser::isWorthWarningAbout`, were modified as such. Both `ClangCodeParser` and `PureDocParser` made use of `CppCodeParser` methods in the call chain for the virtual `parseSourceFile` method, the entry point to the parsing of a source file. All the usages are required to process the extracted QDoc comment-blocks in-place. Due to the hierarchy changes, both objects do not have access to the required methods anymore. As this dependency cannot be directly removed at this point, `CodeParser::parseSourceFile` interface was modified to require a `CppCodeParser` instance, to allow for the required in-place processing. Thus, `ClangCodeParser::parseSourceFile`, `PureDocParser::parseSourceFile` and `QmlCodeParser::parseSourceFile` had their signature update to respect the new interface. `QmlCodeParser` does not make use of `CppCodeParser` provided methods and thus had no implementation change for `parseSourceFile`. `ClangCodeParser` makes direct usages of certain `CppCodeParser` methods in `parseSourceFile` and was thus modified to access them through the passed in `CppCodeParser` instance. `PureDocParser` makes use of `CppCodeParser` methods in `processQDocComments`, the actual processing logic for the parser, as called by `parseSourceFile`. Hence, `PureDocParser::processQDocComments` was modified to receive an instance of `CppCodeParser`. The instance is passed directly by `parseSourceFile` and each call to `CppCodeParser` method was modified to use the passed in instance. Certain methods for `CppCodeParser` that are accessed by either `ClangCodeParser` or `PureDocParser` were protected. To allow the access to continue now that the classes aren't related those methods are now public under `CppCodeParser`'s interface. In particular, `CppCodeParser::hasTooManyTopics`, `CppCodeParser::processTopicArgs`, `CppCodeParser::processMetaCommand` and the two overloads of `CppCodeParser::processMetaCommands` were modified as such. Due to `parseSourceFile` now requiring a `CppCodeParser` instance, its only usage, in `processQDconFile`, was modified to obtain such an instance. The instance is built in-place, once per call, in the smallest scope that respects those requirements near the call to `parseSourceFile`. Precedently, the manual lifetime management derived by `CodeParser` would scope a `CppCodeParser` implicit instance, as provided by `ClangCodeParser` and `PureDocParser`, as the whole of `processQDocConf`. As the only usages of `CppCodeParser` is through direct calls to `parseSourceFile`, the new scope, while smaller, still ensures that the object is long-lived enough for its usages. All state that `CppCodeParser` depends upon, as the `CodeParsers` is either instance based or `processQDocConf` scoped and thus no semantic changes should derive from the instancing scope. The change, while invasive, is not expected to change any of the output documentation for QDoc, preserving the same semantic as before. Change-Id: Iae448be6c6975649044aa08ed334c73faa38bddf Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* QDoc: Remove `CppCodeParser::metaCommands`Luca Di Sera2023-03-191-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As part of extracting user-provided documentation, QDoc has to parse a variety of source files in a variety of languages. `CodeParser` is the base class of objects that take care of performing this parsing process in QDoc. When extracting the documentation in one of the `CodeParser`s QDoc generally tries to parse the extracted documentation in-place. The documentation has a series of available commands that might depend on the currently used parser. To support this process some of the `CodeParser` child classes provides series of methods to retrieve the required commands for each parser. `CppCodeParser`, the parser that provides the semantic for QDoc's comment-blocks, for example, provides `metaCommands`, to list the available "meta commands" in a comment-block. `metaCommands` returns a static member, `metaComamnds_`. This static member is initialized during the construction of an `CppCodeParser` instance, and the initialization is made so that it doesn't run more than once, albeit this is done in a non-thread-safe way. The initialization is based on `CppCodeParser::common_meta_commands`, as a base, plus some other commands that are not in `common_meta_commands`. Generally, this process could be better expressed by the use of a static with in-place initialization. There are two probable reasons why this has not been the way it was written in the past. Supposedly, when this code was written, there was no suitable way to initialize a `QSet<QString>`, the type of `metaCommands_`, in-place, as similar patterns can be found in other legacy parts of QDoc that are confirmed to have had this issue due to their age. Additionally, the expansion of the `COMMAND_*` macros, which form the content for `metaCommands_`, were, until recently, dependent on certain data being available in another part of the system, so that expanding them in a static context that would be processed before this data was available would incur into a series of errors. This dependency was removed in a recent patch, so that the issue is no more. Hence, the `metaCommands()` method is removed, along with `metaCommands_`, in favor of a public static, `meta_commands`, that is initialized in-place, to simplify the related code. All usages of `meta_commands` were modified to refer to `CppCodeParser::meta_commands`, keeping an equivalent semantic, as a consequence of the change. As the initialization of `metaCommands_` was the only thing that was being done in the constructor for `CppCodeParser`, the constructor was removed in favor of a default one. Change-Id: I6e54b95a50d07a394d727c0af8c409599a088d4c Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Remove `CppCodeParser::topicCommands`Luca Di Sera2023-03-191-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As part of extracting user-provided documentation, QDoc has to parse a variety of source files in a variety of languages. `CodeParser` is the base class of objects that take care of performing this parsing process in QDoc. When extracting the documentation in one of the `CodeParser`s QDoc generally tries to parse the extracted documentation in-place. The documentation has a series of available commands that might depend on the currently used parser. To support this process some of the `CodeParser` child classes provides series of methods to retrieve the required commands for each parser. `CppCodeParser`, the parser that provides the semantic for QDoc's comment-blocks, for example, provides `topicCommands`, to list the available "topic commands" in a commnet-block. `topicCommands` initializes a static member, `topicCommands_` and then returns it, avoiding initialization if the method is called more than once. While this process can be better expressed by the simple use of a `static` there are two probable reason for why it wasn't done in this way. Supposedly, when this code was written, there was no suitable way to initialize a `QSet<QString>`, the type of `topicCommands_`, in-place, as similar patterns can be found in other legacy parts of QDoc that are confirmed to have had this issue due to their age. Additionally, the expansion of the `COMMAND_*` macros, which form the content for `topicCommands_`, were, until recently, dependent on certain data being available in another part of the system, so that expanding them in a static context that would be processed before this data was available would incur into a series of errors. This dependency was removed in a recent patch, so that the issue is no more. Hence, the `topicCommands()` method is removed, along with `topicCommands_`, in favor of a public static, `topic_commands`, that is initialized in-place, to simplify the related code. All usages of `topicCommands` were modified to refer to `CppCodeParser::topic_commands`, keeping an equivalent semantic, as a consequence of the change. Change-Id: I9de2332bf557254e7ffd33290e6af678c2b121aa Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Remove `ClangCodeParser::m_version`Luca Di Sera2023-03-161-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `ClangCodeParser`, the class that takes care of handling and parsing C++ source files to extract the user-provided documentation, will try to automatically find the element in the code that some documentation block refers to if that documentation block has no topic command. Whend doing so and failing, it will generally try to report a warning to the user. The warning is emitted based on certain conditions. In particular, if the documentation block exposes a "\since" command, a command that specifies from which version of the project the documented element is available, and the version specified by the command is a future version of the project, the warning is not emitted. The current version of the project is provided by the configuration that QDoc reads when compiling. `ClangCodeParser` copies that version and keeps it stored in an instance-scoped member, `m_version`, so that it can compare it to the one provided by a "\since" command. As `m_version` is used only for this comparison, which is located in a single function call, we remove `m_version` and directly access the value in the config, which is not expected to change at any point in the execution of QDoc, in-place. Hence, the `m_version` member was removed. Its initialiazation in `ClangCodeParser::initializeParser` was removed as a consequence. Furthermore, its single usage in `ClangCodeParser::parseSourceFile` was supplanted with a direct access to the configuration stored version. Change-Id: Ie607fa3b74b4f9c9e3fba82a98a8f2f601018f70 Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Remove `CodeParser::m_moduleHeader`Luca Di Sera2023-03-161-9/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QDoc parses a series of source file in different languages and formats to find the user-provided documentation. The base parsing interface for elements that perform this process is given by the `CodeParser` class, with the concrete implementation of the process for different languages/formats give by its child classes. `CodeParser`, as part of its interface, provides certain methods that are only meaningful when processing specific programming languages source. For example, it exposes `CodeParser::setModuleHeader` and `CodeParser::moduleHeader` which are used to provide an PCH-able header file for the C++ headers that will be parsed for a project. Those methods are implemented in the `CodeParser` base-class, along as setter and getter for the instance-state `m_moduleHeader`. Nonetheless, they are only meaningful when running through the `ClangCodeParser` `ClangCodeParser` child class, which actually implements the processing of C++ source files. Those, `m_moduleHeader`, `setModuleHeader` and `getModuleHeader` are now removed from `CodeParser`. `ClangCodeParser` only requires knowledge of the module header in its private method `CLangCodeParser::buildPCH`, where the module header is used to actually produce a precompiled header that will later be used by further call to Clang when parsing C++ source files. Hence, instead of moving the `m_moduleHeader` instance state to `ClangCodeParser`, `buildPCH` and its public entry point `ClangCodeParser::precompileHeaders` were modified to require a `QString` parameter that is equivalent to the original value set through `setModuleHeader`, so as to reduce the of the state to its current lowest. The value of a "module header" is generally given through the configuration for the currently built project and was previously extracted in "main.cpp" and set through `setModuleHeader`. As a consequence of the above changes, the code that took care of setting the module header was modified to pass the relevant value directly to the single call of `ClangCodeParser::precompileHeaders`. Furthermore, the above code was moved directly adjacent to the call to `precompileHeaders` so that it appears nearer to its usage site. Change-Id: I1d4db2fba2807b69e23e182197a78796a2a4675f Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* qdoc: Remove unnecessary Config access functionsTopi Reinio2023-03-141-3/+3
| | | | | | | | | | | | | | | | | | Config class now provides Config::get(), returning a ConfigVar reference which can be further converted to string, list, set, int, or bool. Use get() throughout the codebase and remove the old access functions. In addition, make Config::get() return a const reference, and prevent an unnecessary contains() check by using an iterator. Do some drive-by cleaning of related code. Change-Id: I2ff2203824cd4ae80c4615080948565219ad20b2 Reviewed-by: Paul Wicking <paul.wicking@qt.io> Reviewed-by: Luca Di Sera <luca.disera@qt.io>
* QDoc: Move `CodeParser::parseHeaderFile` to `ClangCodeParser`Luca Di Sera2023-03-101-13/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QDoc parses a series of source file in different languages and formats to find the user-provided documentation. The base parsing interface for elements that perform this process is given by the `CodeParser` class, with the concrete implementation of the process for different languages/formats give by its child classes. `CodeParser`, as part of its interface, provides certain methods that are only meaningful when processing specific programming languages source. For example, it exposes `CodeParser::parseHeaderFile` whose purpose it to provide an entry point for parsing C++ header files. The method is only meaningfully implemented and used in the `ClangCodeParser` child class, the class that actually implements the processing of C++ source files. Hence, the method is now removed from `CodeParser`'s interface and directly exposed as part of the interface of `ClangCodeParser`, to reduce the surface of the method and to reduce the dependencies between `ClangCodeParser` and the `CodeParser` interface, which is generally expected to be removed in the future. `CodeParser` are, currently and temporarily, mostly initialized statically and then retrieved through certain methods of the `CodeParser` interface. `CodeParser::parserForHeaderFile` is one such method that would retrieve a `CodeParser` or child class instance that is able to parse an header file. Due to the removal of `parseHeaderFile` from `CodeParser` interface and the fact that only one specific parser is able, and should be able, to parse header files, `CodeParser::parserForHeaderFile` was removed. Its only usage in "main.cpp", where it was called to retrieve the already available `ClangCodeParser`, was modified to make use of `ClangCodeParser` directly. An auxiliary method, `CodeParser::headerFileNameFilter`, previously used only by `CodeParser::parserForHeaderFile`, which provided a list of extensions to identify what files could be accepted by a certain parser as header files, is now removed as dead code. A non-meaningful reimplementation of the `headerFileNameFilter` method in `CppCodeParser`, a child class of `CodeParser`, was removed as of consequence. Similarly, the same method implementation in `ClangCodeParser` was removed. The filtering functionality that the method indirectly provided when used by `CodeParser::parserForHeaderFile`, which is to be retained for backward compatibility reasons, was moved to `processQdocconfFile` in "main.cpp", where the header files that should be parsed are gathered. Instead of using the `headerFileNameFilter` method, the data that was provided by it is now exposed as a static member of `ClangCodeParser` and accessed directly when filtering is necessary. Change-Id: Iff9a204627675aa7b34232c114945afceb8313ff Reviewed-by: Topi Reiniö <topi.reinio@qt.io> Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* QDoc: Remove `ClangVisitor::m_friendDecl`Luca Di Sera2023-03-101-5/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QDoc parses C++ code that is part of a documentation project through the use of a Clang-based parser, using the extracted information both to find user-defined documentation and to check that it has certain qualities. QDoc extracts that kind of information by traversing the AST produced by calls to Libclang, Clang's C API, and slowly lowering that AST into a custom AST made of `Node`s. This traversal is generally handled by `ClangVisitor` as called by `ClangCodeParser`, the top level interface for parsing C++ source and header files. When a function/method is defined as `friend` of a certain element, QDoc extracts that information and specially marks the corresponding `Node` so that it can be categorized and highlighted in a certain way when shown to the user. In the AST that Clang produces, such an element that is marked as a `friend` produces an AST node, `FriendDeclaration`, or a cursor of kind `CXCursor_FriendDecl`, whose child is the marked element. `ClangVisitor` is built so that, while traversing the AST, no context is preversed between the inspection of each node. Furthermore, the traversal is one-directional, so that no information found in child elements is bubbled up to a previous step of the traversal. With those self-imposed restrictions in mind, to handle the information of a declaration being a `friend`, a boolean member `ClangVisitor::m_friendDecl` is used. The member is set to `true` when a `CXCursor_FriendDecl` is found, inspected at a later point in the traversal of the cursor children, and finally set back to `false` when all the children of the cursor have been visited. The `m_friendDecl` member was then used while processing other elements of the AST to discern whether the element that was being processed should be marked as a `friend` or not. Due to the recursion of the AST, the place where the boolean flag was set and the place where it was actually used could be quite apart, sometimes down many levels of a call stack, reducing the locality and scrutability of the downstream code. Due to the instance-scope of the member, extraneous children of a `CXCursor_FriendDecl` could be evaluated as `friend`s even when that could not have a valid semantic. Similarly, due to the mutability of the member and its excessive scope, care was required to ensure that the flag was reset at the correct point during the traversal, extending the mental load required to understand the code and the possible classes of bugs. To simplify the code, `m_friendDecl` is now removed, in favor of in-place, AST-based checks to evaluate whether an element is a `friend` or not. The member variable was removed from the instance, along with its single write access in `ClangVisitor::visitHeader`. Additionally, its single read access in `ClangVisitor::processFunction` was modified to retrieve the `friend` information through Clang's APIs. Specifically, the C++ API from Clang, which has been introduced by recent changes in QDoc that allows it to be used along with Clang's C API, is used to obtain such information, through the `Decl::getFriendObjectKind`, as it is more expressive and more direct than the required C API's calls. Certain unnecessary comments in the touched code were removed as they were providing no useful information. The change does not impact the produced documentation and is expected to be semantically equivalent to the behavior of the previous code. Change-Id: Ifb453ac6d29fa9e2db90f311a1656c95b9dcd712 Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* QDoc: Remove `CodeParser::m_currentFile`Luca Di Sera2023-03-071-1/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `CodeParser`, the base class for parsers of input source file in QDoc, exposed an internal member that stored the path of the file that was currently being parser by an instance of `CodeParser`. The member was set when a new file was being parsed, and required to be handled by all downstream parsers, both in setting and in clearing it at the correct point. Nonetheless, the member is generally unrequired and was indeed not used, as the scope and usages of the path of a parsed file is well-defined and limited during parsing. The presence of the member is a source of bugs. Indeed, not all child classes where correctly handling the lifetime of the member. Further, it generally adds maintenance cost to the child classes and hinders the creation of new derived classes as it increases the mental load and implicit knowledge that is required to implement a `CodeParser`. Hence, the member and all references to it were removed in `CodeParser` and its child classes; to simplify the codebase, remove unnecessary state, avoid the additional classes of bugs that would exist if the member was ever read and as the member represented dead code. `CodeParser::currentFile`, a getter for `m_currentFile`, was removed as a consequence of the member removal. Change-Id: If5b5538d038a073d8288a644fe39d3dddc1d89c8 Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Use clang's C++ API to extract parameters' types from a functionLuca Di Sera2023-02-161-10/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QDoc uses clang's C API, LibClang, to parse the source code of C++ projects, so as to be able to extract the user-written documentation and provide certain guarantees about its correctness. When QDoc encounters a function, method or similar element, it extracts the types of the parameters of the element, both to show them to the user and to compare them to the one provided by the user in a certain document-block, to ensure consistency. LibClang has a good support for those kind of extraction, such that they are used to perform this effort in `ClangCodeParser::processFunction`, the method that generally execute this process to enrich a `FunctionNode`, the internal representation for documentable elements that are callable, with the relevant information. Recent changes to QDoc allows us to interleave usages of Clang's C and C++ API, something that was done for certain parts of `ClangCodeParser::processFunction` that could not be easily represented with the more limited LibClang. While there is no particular issue with the interleaving of the two APIs, the two axis on which information is retrieved tend to require certain overlapping operations, which lengthen the code and tend to not mesh well with one another. Thus, we refactor a further part of `ClangCodeParser::processFunction`, to slowly convert it completely to a Clang's C++ API based method. Hence, the code that takes care of extracting information about the type of the parameters of a callable element was rewritten using the equivalent Clang's C++ API calls. Change-Id: I365cd1257b2a6a07187dbf23a971244b4c1f2daf Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* qdoc: Improve Q_PROPERTY parsing for the property typeTopi Reinio2023-02-141-17/+31
| | | | | | | | | | | | | | | | | | | | | | | | | QDoc had a naive strategy for parsing Q_PROPERTY() macro arguments for resolving the type and name; when the argument string is separated by spaces, the first item was assumed to be the type, and the second item the name. This failed for following valid declarations: Q_PROPERTY(QMap<QString, QString> map ...) // type contains a space Q_PROPERTY(Type * handle ...) // '*' interpreted as the name Fix this by locating the first property attribute and then splitting the input at that boundary. This allows QDoc to extract the property type and name without making any assumptions about their syntax. Remove old workarounds as unnecessary and implement safeguards for invalid input. Also handle the MEMBER attribute correctly as it implies the property is writable, whether the WRITE accessor is set or not. Pick-to: 6.2 6.4 6.5 Fixes: QTBUG-111093 Change-Id: Ic1bf071a7b003a1cd0cb9a212dabdb7ea00ebfbe Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Luca Di Sera <luca.disera@qt.io>
* QDoc: Use clang's C++ API to recognize copy/move assignment operatorsLuca Di Sera2023-01-261-31/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QDoc uses clang's C API, LibClang, to parse the source code of C++ projects, so as to be able to extract the user-written documentation and provide certain guarantees about its correctness. When QDoc encounters a copy or move assignment operators, it marks its internal representation of the element with this information, which is later used to organize, order and render the documentation for the element. As LibClang does not provide first party support for extracting this information, a manual way to retrieve the information based on the spelling of the function and the value category of the argument of the processed operators was performed. This implementation was historically bugged. As it did not follow the specification for copy/move operators it was able to recognize many false positives and unable to recognize certain copy/move operators. To solve the issue a series of patches were pushed upstream to LLVM, exposing the required functionality of the C++ API to LibClang, which was expected to be available with version 16, with the intention of holding a fix until the upgrade to that new version was available. Recent changes to QDoc allows us to turn to clang's C++ API, which is more complete, on the spot from a LibClang's cursor thus not requiring any more waiting time to solve the bugged implementation. Hence, the detection method for copy/move assignment operators was revamped in term of the C++ API, resolving the above mentioned issues. `ClangCodeParser::processFunction` is the method that generally takes care of extracting this form of information, enriching a `FunctionNode`, the internal representation for documentable elements that are callable, with the retrieved information. `ClangCodeParser::processFunction` would perform ad-hoc checks based on the spelling of the arguments of a processed cursor whose name was "operator=". The ad-hoc checks are thus removed, in favor of calling the `CXXMethodDecl::isCopyAssignmentOperator` and `CXXMethodDecl::isMoveAssignmentOperator` methods. Change-Id: I68b9f921d76a67656509190adb3221c3b383bdab Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Use clang's C++ API to recognize copy/move constructorsLuca Di Sera2023-01-261-34/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QDoc uses clang's C API, LibClang, to parse the source code of C++ projects, so as to be able to extract the user-written documentation and provide certain guarantees about its correctness. When QDoc encounters a copy or move constructors, it marks its internal representation of the element with this information, which is later used to organize, order and render the documentation for the element. As LibClang does not provide first party support for extracting this information, a manual way to retrieve the information based on the spelling of the argument of the processed constructors was performed. This implementation was historically bugged. As it did not follow the specification for copy/move constructors it was able to recognize many false positives and unable to recognize certain copy/move constructors. Recent changes have solved some of the bugs that were acting as blocker for other features but the implementation was left bugged as a by-specification recognizer would have required a relative huge amount of bug-prone work. To solve the issue a series of patches were pushed upstream to LLVM, exposing the required functionality of the C++ API to LibClang, which was expected to be available with version 16, with the intention of holding a fix until the upgrade to that new version was available. Recent changes to QDoc allows us to turn to clang's C++ API, which is more complete, on the spot from a LibClang's cursor thus not requiring any more waiting time to solve the bugged implementation. Hence, the detection method for copy/move constructors was revamped in term of the C++ API, resolving the above mentioned issues. `ClangCodeParser::processFunction` is the method that generally takes care of extracting this form of information, enriching a `FunctionNode`, the internal representation for documentable elements that are callable, with the retrieved information. `ClangCodeParser::processFunction` would perform ad-hoc checks based on the spelling of the arguments of a processed cursor that was a constructor. The ad-hoc checks are thus removed, in favor of calling the `CXXConstructorDecl::isCopyConstructor` and `CXXConstructorDecl::isMoveConstructor` methods. Certain constructors in the generated documentation may now be re-ordered or marked differently in the output documentation if they were incorrectly recognized or not recognized as copy/move constructors. Change-Id: Id4e88cfa682b13899dd42af9c952f1316849dfee Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Use clang's C++ API to mark element explicitLuca Di Sera2023-01-261-32/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QDoc uses clang's C API, LibClang, to parse the source code of C++ projects, so as to be able to extract the user-written documentation and provide certain guarantees about its correctness. When an element is marked as "explicit", QDoc extracts that information and provides it in the produced output documentation in a user-visible way. As LibClang does not provide first party support for extracting "explicit" information, a workaround was provided to perform this operation where the source code of the processed element was tokenized and the element was marked "explicit" if an "explicit" keyword appeared within its tokens. This approach is feeble. Indeed, the code that performed this process was bugged. Certain elements whose code was generated from or contained macros might not have been tokenized correctly as to expose an "explicit" specifiers or might have contained non-relevant "explicit" keyword that was misinterpreted. Certain elements of this issue could be solved directly in LibClang, with a more thorough manipulation of the relevant cursors before tokenization, but would require a huge amount of work to identify and cover various possible cases. Recent changes to QDoc allows us to turn to clang's C++ API, which is more complete, on the spot from a LibClang's cursor. The C++ API has first-party support for "explicit" detection and can thus ensure that all relevant cases are taken care of correctly. Hence, the "explicit" detection method was revamped in term of the C++ API, resolving the above mentioned issues. `ClangCodeParser::processFunction` is the method that generally takes care of extracting this form of information, enriching a `FunctionNode`, the internal representation for documentable elements that are callable, with the retrieved information. `ClangCodeParser::processFunction` would call the free-function `get_specifiers`, which performed the tokenization method to extract specifiers-related information, producing a `CXXSpecifiers` instance, that contains data about the presence or lack thereof of certain specifiers which QDoc support. The produced instance was then used to mark the processed `FunctionNode` based on the information that were extracted. `ClangCodeParser::processFunction` was modified not call `get_specifiers` anymore, instead retrieving it trough clang's C++ API's `isExplicit` method. `get_specifiers` was thus removed as it had no usage anymore. `CXXSpecifiers` was similarly removed due to lack of usage. Certain elements of Qt's documentation that were incorrectly marked "explicit" will now avoid the erroneous marking. For example, certain friend operators of `QExplicitlySharedDataPointer`, whose source code was incorrectly tokenized due to the presence of certain macros. Similarly, certain elements of Qt's documentation that were not correctly marked as "explicit" will now provide the correct user-visible information. For example, certain constructors of `QChar` whose "explicit" specifier was generated by a macro. Change-Id: I33a86a4d63c67432606c7dd442d69d6a11762c89 Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Use clang's C++ API to mark element constexprLuca Di Sera2023-01-261-7/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QDoc uses clang's C API, LibClang, to parse the source code of C++ projects, so as to be able to extract the user-written documentation and provide certain guarantees about its correctness. When an element is marked as "constexpr", QDoc extracts that information and provides that information in the produced output documentation in a user-visible way. As LibClang does not provide first party support for extracting "constexpr" information, a workaround was provided to perform this operation where the source code of the processed element was tokenized and the element was marked "constexpr" if a "constexpr" keyword appeared within its tokens. This approach is feeble. Indeed, the code that performed this process was bugged. For methods/functions whose definition was inline, the tokenized source code would be contain the body, where the "constexpr" keyword can appear in non-specifier contexts (e.g `if constexpr`), resulting in false positives being marked as "constexpr". Similarly, certain elements might be implicitly "constexpr" even if no `constexpr` specifier appears in their declaration/definition, such as certain defaulted constructors. Recent changes to QDoc allows us to turn to clang's C++ API, which is more complete, on the spot from a LibClang's cursor. The C++ API has first-party support for "constexpr" detection and can thus ensure that all relevant cases are taken care of correctly. Hence, the "constexpr" detection method was revamped in term of the C++ API, resolving the above mentioned issues. `ClangCodeParser::processFunction` is the method that generally takes care of extracting this form of information, enriching a `FunctionNode`, the internal representation for documentable elements that are callable, with the retrieved information. `ClangCodeParser::processFunction` would call the free-function `get_specifiers`, which performed the tokenization method to extract specifiers-related information, producing a `CXXSpecifiers` instance, that contains data about the presence or lack thereof of certain specifiers which QDoc support. The produced instance was then used to mark the processed `FunctionNode` based on the information that were extracted. `ClangCodeParser::processFunction` was modified to avoid processing "constexpr"-related information from the produced `CXXSpecifiers`, instead retrieving it trough clang's C++ API's `isConstexpr` method. `get_specifiers` was modified so as to not extract any "constexpr" information anymore, due to the now missing usage for that information. `CXXSpecifiers` was in turn modified to not store any "constexpr"-related information, for the same reason. Any documentation that contained non-constexpr inline-methods whose body contained the `constexpr` keyword will have its output documentation modified by this change, removing the produced "constexpr" tag from those method, which were false positives. Any documentation that contained implicitly constexpr methods will have its output documentation modified so that those methods will now be marked as "constexpr". Change-Id: Ib47b58db200905f95f8358bcc363ff1187f01741 Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* qdoc: Ensure the generated temporary header file is closed properlyTopi Reinio2023-01-261-3/+1
| | | | | | | | | | | | | Use the correct scope for the QFile object used for writing the temporary header file; this ensures that the associated QTextStream object is destroyed first and its contents flushed before destroying the QFile, potentially leading to truncated writes to the file. Pick-to: 6.5 6.4 6.2 5.15 Done-with: Simon Geisseler Fixes: QTBUG-109614 Change-Id: Ic6a68c0b52219ce607a5116c730862ee0cb37f04 Reviewed-by: Luca Di Sera <luca.disera@qt.io>
* QDoc: Tag C++ elements as "noexcept" when they are marked as suchLuca Di Sera2023-01-251-0/+50
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | C++'s allows certain declarations to be marked by the `noexcept` specifier, so as to signify that the element will not throw any exception. A `noexcept` specifier might be unconditional, such the the relevant element is always to be considered "noexcept", or conditional, such that the element is or is not "noexcept" based on the evaluation of a compile-time, user-defined expression. This information is important to the user of an API, as it may dictate when and how they can use a certain element. Nonetheless, up to now, QDoc would not treat the "noexcept" specifier, such that this information was lost between source-code and documentation. To avoid the issue and ensure that users are given a way to discern whether something is marked "noexcept" or not, QDoc will now "tag" a relevant documentable element that is a callable, such as a C++ method, as "noexcept" when the `noexcept` specifier appears in its declaration or the element is implicitly noexcept (e.g destructors). To store this information, `FunctionNode`, the internal representation for "callable" documentable elements, such as a C++ constructor or method, was modified to expose an optional string, `m_noexcept`, trough the setter, `markNoexcept` and the getter, `getNoexcept`. `markNoexcept` allows the element as being "noexcept". Optionally a string can be provided which represents the expression of a conditional "noexcept". `getNoexcept` returns an optional value. If the value is Nothing, the element is to not be considered "noexcept". If the value is Just, it will contain a string that represents the condition under which the element is "noexcept". An empty string is to be considered marking a non-conditional "noexcept". Generally, this kind of information is extracted from the codebase in `ClangCodeParser::processFunction`, where an instance of a `FunctionNode` is populated based on the Libclang-provided `CXCursor` that generated it. LibClang has only partial support for the `noexcept` specifier. It allows the extraction of a `CXCursor_ExceptionSpecificationKind`, which provides information about the present or not of a `noexcept` specifier, but it doesn't provide a direct way to extract the expression of a conditional `noexcept` specifier. The expression of a conditioanl `noexcept` specifiers should generally be, in some way, presented to the user, as the user would not otherwise be able to ascertain whether an element is "noexcept" or not in its use case, thus requiring us to extract it in some way. For similar issues, we have generally taken to tokenizing the source code to manually extract the required information. For the specific case of a `noexcept` specifier, we consider this unfeasible due to grammar of of the C++ language. In a function signature, in particular due to the existence of the `noexcept` operator, an operator that returns whether an expression is "noexcept" or not, the `noexcept` keyword can appear many times, in many places with different meanings. The extraction of the very specific `noexcept` specifier, and its expression should it be conditional, is thus hindered so that it is not easy to cover all possible cases without actually parsing the signature itself. To be able to find the information we are looking for, we drop down from LibClang's to clang's C++ AST, which provides full support for this kind of extraction. To do so, a new function, `get_cursor_declaration`, is added to "src/qdoc/clangcodeparser.cpp". Each `CXCursor` in LibClang stores a reference to the C++ AST element that generated it. `get_cursor_declaration` extracts this information, for CXCursors that represent a declaration, and returns the underlying C++ AST node, which can be used to access the more thorough functionalities that the C++ AST provides. `ClangCodeParser::processFunction`, was modified to call `get_cursor_declaration` for its processed elements. From the retrieved declaration, the normal methods of the C++ AST are used to extract information about the presence, or lack thereof, of a `noexcept` specifier and its expression, should it be conditional. This information is then stored into the processed `Node`, using the newly introduced `markNoexcept`. Later on, during the "Generation Phase", where QDoc destructures the provided documentable elements to produce the final output documentation, QDoc will call a `CodeMarker` to generate the set of "tags", small strings that appear near the detailed documentation of an element, to enhance the final documentation with certain information about the documented element. To make use of the now stored "noexcept" information, `CodeMarker::extraSynopsis`, which is the particular methods that generates the relevant set of "tags" for an element, was modified to take into account the "noexcept" information of a `FunctionNode`. If the `FunctionNode` is marked as "noexcept" a tag will be produced. If the "noexcept" is not conditional, a "noexcept" tag is produced. If the "noexcept" is conditional, a "noexcept(...)" tag is produced. When this is the case, additional information will be generated for the detailed documentation of the relevant element to provide more information about the conditionality of the "noexcept". That is, a not will be produced that contains the expression that the "noexcept" is conditioned on. To do so, a new method `generateNoexceptNote` was added to `Generator`, the base class of the components that take care of producing the effective output during a QDoc execution. The method is implemented using the same pattern of similar procedures, such as `Generator::generateSince`, where, starting from the processed `Node`, a `Text`, an internal representation for certain formatted output, instance is produced and delivered to `Generator::generateText`, which takes care of producing the marked-up output documentation. In particular, a note element containing the extracted conditional expression and a small text about the lack of exceptions depending on this expression is produced. `HtmlGenerator`, the child class of `Generator` that specifically generates the HTML formatted output documentation, was modified to call the `Generator::generateSince` method when producing the detailed documentation of an element. The conditional expression for a `noexcept` specifier, while necessary for the user to see, might not necessarily be legible without additional context. This context cannot generally be auto-generated and, thus, the specific format in which we present this information is not to be considered final and is expected to change in the near future. When QDoc parses the source code for a project, it generates an XML-based "index" file, containing certain information about the extracted documentable elements that can be consumed by external tools and is consumed by QDoc itself to enable cross-module linking. To allow the newly added "noexcept" information to be retained between modules and to enable the inspection of such information for external consumers, `QDocIndexFiles::generateFunctionSection`, which writes the relevant information about a `FunctionNode` in the index file, was modified to write a "noexcept" attribute in the XML-element representing the `FunctionNode`. The attribute is elided when the `FunctionNode` is not marked as "noexcept", the default state, to save space and avoid cluttering the output. If the "noexcept" is conditional, a further attribute, "noexcept_expression" is written, containing the extracted conditional expression of the "noexcept". Similarly, `QDocIndexFiles::readIndexSection`, which retrieves the information stored in a certain index file and rebuilds the internal representations that QDoc uses for the represented elements, was modified to read the "noexcept" and "noexcept_expression" attributes that were added. If the "noexcept" attribute is present and has a "true" value in a "function" element, the reconstructed `FunctionNode` will be marked as "noexcept", to retain the information. If the "noexcept_expression" attribute is present, the `FunctionNode` will further contain a copy of the conditional expression in string form. The regression files for `tst_generatedOutput` were regenerated to take into account the addition of the new tag. Fixes: QTBUG-93439 Change-Id: Ic6e15c53309db6c4f398c15670fe3f15886bca3e Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Tag C++ elements as "constexpr" when they are marked as suchLuca Di Sera2022-12-281-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | C++'s allows certain declarations to be marked by the `constexpr` specifier, so as to signify that the element can be used in constant expressions contexts. This information is important to the user of an API, as it may dictate when and how they can use a certain element. Nonetheless, up to now, QDoc would not treat the "constexpr" specifier, such that this information was lost between source-code and documentation. To avoid the issue and ensure that users are given a way to discern whether something is marked "constexpr" or not, QDoc will now "tag" a relevant documentable element that is a callable, such as a C++ method, as "constexpr" when the `constexpr` specifier appears in its declaration. To store this information, `FunctionNode`, the internal representation for "callable" documentable elements, such as a C++ constructor or method, was modified to expose a boolean flag, `m_constexpr`, trough the a setter, `markConstexpr`, which enables the flag, and a getter, `isConstexpr`, which allows to peek into the flag value. The flag is initially defaulted to `false` and is set only when the "constexpr" specifier is encountered in the declaration of the relevant element. Generally, this kind of information is extracted from the codebase in `ClangCodeParser::processFunction`, where an instance of a `FunctionNode` is populated based on the Libclang-provided `CXCursor` that generated it. As Libclang does not have direct support for the `constexpr` specifier, at the current point in time, we extract the information based on the tokenized version of the relevant declaration. That is, the source code represented by the relevant `CXCursor`, which will generally represent a declaration, is tokenized by Clang, all keywords tokens that are part of the declaration are inspected and, if a "constexpr" keyword is encountered, we consider the given declaration to be marked "constexpr". To do so, we reuse the infrastructure that was introduced in a recent commit to preserve the information for `explicit` specifiers. The static function `get_specifiers` in "clangcodeparser.cpp", performs the above process, and is now modified to take into account the `constexpr` specifier. The function returns a structure, `CXXSpecifiers`, that contains some minimum information with regards to the specifiers that we are interested into that Libclang does not directly support. The structure is now updated to provide information about the presence, or lack thereof, of a `constexpr` specifier. Similarly, the body of `get_specifiers` was modified to correctly populate this information based on the available tokens. `ClangCodeParser::processFunction`, which calls `get_specifiers`, was modified to take into account the new "constexpr" information in the returned `CXXSpecifiers` value, marking the processed `FunctionNode` as "constexpr" if a `constexpr` specifier was encountered. Later on, during the "Generation Phase", where QDoc destructures the provided documentable elements to produce the final output documentation, QDoc will call a `CodeMarker` to generate the set of "tags", small strings that appear near the detailed documentation of an element, to enhance the final documentation with certain information about the documented element. To make use of the now stored "constexpr" information, `CodeMarker::extraSynopsis`, which is the particular methods that generates the relevant set of "tags" for an element, was modified to take into account the "constexpr" flag of a `FunctionNode`, and generate an "constexpr" "tag" if it is set to `true`. When QDoc parses the source code for a project, it generates an XML-based "index" file, containing certain information about the extracted documentable elements that can be consumed by external tools and is consumed by QDoc itself to enable cross-module linking. To allow the newly added "constexpr" information to be retained between modules and to enable the inspection of such information for external consumers, `QDocIndexFiles::generateFunctionSection`, which writes the relevant information about a `FunctionNode` in the index file, was modified to write a "constexpr" attribute in the XML-element representing the `FunctionNode`. The attribute is elided when the `FunctionNode` is not marked as "constexpr", the default state, to save space and avoid cluttering the output. Similarly, `QDocIndexFiles::readIndexSection`, which retrieves the information stored in a certain index file and rebuilds the internal representations that QDoc uses for the represented elements, was modified to read the "constexpr" attribute that was added. If the attribute is present and has a "true" value in a "function" element, the reconstructed `FunctionNode` will be marked as "constexpr", to retain the information. Task-number: QTBUG-93439 Pick-to: 6.5 Change-Id: I63b18c34d7b9f3d72047ab2ba823d105f5a694e7 Reviewed-by: Luca Di Sera <luca.disera@qt.io>
* QDoc: Tag C++ elements as "explicit" when they are marked as suchLuca Di Sera2022-12-271-0/+30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | C++'s constructors and conversion functions can be marked by the explicit specifier, so that the element cannot participate in implicit conversion and copy-initialization. This information is important to the user of an API, as it may dictate when and how they can use the given constructor or conversion function. Nonetheless, up to now, QDoc would not treat the "explicit" specifier, such that this information was lost between source-code and documentation. To avoid the issue and ensure that users are given a way to discern whether something is marked explicit or not, QDoc will now "tag" a relevant documentable element as "explicit" when the "explicit" specifiers appears in its declaration. To store this information, `FunctionNode`, the internal representation for "callable" documentable elements, such as a C++ constructor or method, was modified to expose a boolean flag, `m_explicit`, trough the a setter, `markExplicit`, which enables the flag, and a getter, `isExplicit`, which allows to peek into the flag value. The flag is initially defaulted to `false` and is set only when the "explicit" specifier is encountered in the declaration of the relevant element. Generally, this kind of information is extracted from the codebase in `ClangCodeParser::processFunction`, where an instance of a `FunctionNode` is populated based on the Libclang-provided `CXCursor` that generated it. As Libclang does not have direct support for the `explicit` specifier, at the current point in time, we extract the information based on the tokenized version of the relevant declaration. That is, the source code represented by the relevant `CXCursor`, which will generally represent a declaration, is tokenized by Clang, all keywords tokens that are part of the declaration are inspected and, if an "explicit" keyword is encountered, we consider the given declaration to be marked "explicit". To do so, a static function `get_specifiers` was introduced in "clangcodeparser.cpp", which performs the above process. The function returns a newly introduced structure, `CXXSpecifiers`, that contains some minimum information with regards to the specifiers that we are interested into that Libclang does not directly support, such as "explicit". `ClangCodeParser::processFunction` will now call this newly introduced function and mark any relevant information in the processed `FunctionNode` based on the returned `CXXSpecifiers` instance. Later on, during the "Generation Phase", where QDoc destructures the provided documentable elements to produce the final output documentation, QDoc will call a `CodeMarker` to generate the set of "tags", small strings that appear near the detailed documentation of an element, to enhance the final documentation with certain information about the documented element. To make use of the now stored "explicit" information, `CodeMarker::extraSynopsis`, which is the particular methods that generated the relevant set of "tags" for an element, was modified to take into account the "explicit" flag of a `FunctionNode`, and generate an "explicit" "tag" if it is set to `true`. When QDoc parses the source code for a project, it generates an XML-based "index" file, containing certain information about the extracted documentable elements that can be consumed by external tools and is consumed by QDoc itself to enable cross-module linking. To allow the newly added "explicit" information to be retained between modules and to enable the inspection of such information for external consumers, `QDocIndexFiles::generateFunctionSection`, which writes the relevant information about a `FunctionNode` in the index file, was modified to write an "explicit" attribute in the XML-element representing the `FunctionNode`. The attribute is elided when the `FunctionNode` is nor marked as "explicit", the default state, to save space and avoid cluttering the output. Similarly, `QDocIndexFiles::readIndexSection`, which retrieves the information stored in a certain index file and rebuilds the internal representations that QDoc uses for the represented elements, was modified to read the "explicit" attribute that was added. If the attribute is present and has a "true" value in a "function" element, the reconstructed `FunctionNode` will be marked as "explicit", to retain the information. Fixes: QTBUG-109370 Pick-to: 6.5 Change-Id: Iab86082cc63d1191024c514bd197aade63e1d4f6 Reviewed-by: Luca Di Sera <luca.disera@qt.io>
* qdoc: Fix various clang warningsFriedemann Kleint2022-12-021-1/+1
| | | | | | | | | | | | - remove unused variables - Use QString::arg() with multiple string arguments - Avoid detaching containers in loops Pick-to: 6.4 Change-Id: I9b29f5a0269f288b7de862eccdcee9750248dce8 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io> Reviewed-by: Topi Reiniö <topi.reinio@qt.io> Reviewed-by: Luca Di Sera <luca.disera@qt.io>
* qdoc: Cache source files when retrieving code snippetsFriedemann Kleint2022-11-251-9/+45
| | | | | | | | | | | qdoc often retrieves the contents of a source file and matching headers via the clang cursors when parsing. Cache the last files except the dummy file to avoid reading the same file many times. This avoids roughly 43000 file reads in qtbase. Pick-to: 6.4 6.2 Change-Id: I33fcc57039acfc667e095e782cdd6eb4f592028b Reviewed-by: Luca Di Sera <luca.disera@qt.io>
* qdoc: Avoid C++ parsing issues when linking against libclang 15Topi Reinio2022-11-241-0/+10
| | | | | | | | | | | | | | | | | libclang from LLVM version 15 causes a lot of parsing failures with the 'error code: 4' specifically when initialized with C++20 support. This problem is highly likely to be fixed in LLVM 16 release. Drop down to C++17 standard if libclang from LLVM 15 is detected. There are a few places in the Qt API where certain features are conditionally enabled for C++20 in a way that's also visible in the generated documentation. These can be worked around separately. Pick-to: 6.4 Fixes: QTBUG-94365 Change-Id: I5a3fd14dfe07102595fc941b27c46688b0f29697 Reviewed-by: Luca Di Sera <luca.disera@qt.io>
* QDoc: Hack-fix to correctly mark some nodes as copy-constructorsLuca Di Sera2022-11-171-5/+57
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QDoc represents documentable elements extracted from source code as elements of the `Node` class and its derivatives. In particular, it represents C++ function, methods and so on as inhabitants of `FunctionNode`. `FunctionNode` stores a simplified view of the properties of such an element that are later used by QDoc to perform some sanity checks and to actually generate the documentation for the element. One such property, the "metaness", indicates what kind of element the inhabitant of a `FunctionNode` might actually represent. The "metaness" is generally set to identify some special cases that later branch the execution of code and command the way in which the documentation for the element is generated. For example, due to the desire to sort the methods of a C++ class when QDoc is listing its element, a special metaness is assigned to, for example, constructors, move-constructors and copy-constructors. The "metaness" of a `FunctionNode`, together with some of its other properties, is generally set by QDoc while parsing the various source files through `ClangCodeParser` and, specifically, in `ClangCodeParser::processFunction`, where an instance of a `FunctionNode` is populated by its equivalent code-level libclang `CxCursor`. The condition that would identify whether a `FunctionNode` should have a metaness representing a copy-constructor was bugged since its introduction. In particular, the current implementation considers the spelling of the type of the parameters of a method, if it is a constructor, and marks it as a copy-constructor when a parameter that is a reference is spelled exactly the same as the parent class of the method. That is, when a constructor "X" of class "X" has a parameter "X&". This specific implementation that used the spelling, failed to identify the very general usage of const-references in a copy constructor. When the type of a parameter is qualified, such as with "const", libclang will consider that qualifier in its spelling unless removed, for which there is no direct method in pre-16 libclang. The implementation would remove the reference part, "&" or "&&", through `clang_getPointeeType`, which is further incorrect as it would work for pointer types too, but would not address any of the possible qualifiers in the spelling. Then, it would directly check the spelling to the name of the constructor, that is, the name of the containing class. Not addressing the qualifiers would thus fail for reference types that were qualified. For example, a constructor "X" with an argument of type "const X&" would be spelled by libclang as "const X" but would be compared by the implementation to "X", thus always failing. This was particularly visible for copy-constructors, as the most common way to implement a copy-constructor is with a unary-constructor whose argument is of type "const X&". Indeed, in the years since this code was implemented, QDoc never actually identified the "metaness" of copy-constructor correctly, albeit, fortunately, with little impact on the produced documentation. To avoid the issue, qualifiers are now handled in "ClangCodeParser::processFunction" when identifying the metaness of a constructor. While this solves the issue at hand, "ClangCodeParser::processFunction" is still bugged with regards to its intention in multiple ways, such as considering all arguments for the "metaness" checks or not correctly handling the non-common cases of copy/move-assignment-operators. An annotation was added to the code to handle the issue when LLVM16, where a series of patches that we pushed upstream will be available, will be out, as it will allow us to greatly simplify the code and correct the bugs as the same time. The remaining bugs are not expected to be corrected at the current time due to the unnecessary complexity of the required handling due to the current limitation in libclang's AST. The bug are considered safe to preserves for a limited amount of time as they do not generally impact the way in which the Qt Project writes the relevant code-elements, and are only dangerous when some specific cases would otherwise be encountered. The output documentation will not currently be affected by this change, albeit the produced "index" files, an intermediate representation of the code that QDoc produces that is generally consumed both by QDoc and externel consumers, will incur modifications due to the corrected identifying of the copy-constructors. Change-Id: I59ec2c897106a34300b91a175664c0ba07d28f5c Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* qdoc: Query system include paths from the compiler on LinuxTopi Reinio2022-11-141-2/+4
| | | | | | | | | | | | | | | | | | | In certain situations depending on the build environment and the libclang version that QDoc links against, Clang may be unable to resolve the correct system include paths automatically. This seems to be the case particularly for the portable QDoc binary that is provisioned into test builds in the CI system, and results in spurious documentation warnings. Query the paths from GNU C++ compiler on Linux, just like we already do for macOS/clang++. Pick-to: 6.4 Task-number: QTBUG-108353 Change-Id: I92ffb4da0ce8af166084eb20a29ec4b00c047489 Reviewed-by: Luca Di Sera <luca.disera@qt.io> Reviewed-by: Kai Köhne <kai.koehne@qt.io>
* qdoc: ClangCodeParser: Remove unnecessary global nodes from the treeTopi Reinio2022-10-271-0/+6
| | | | | | | | | | | | * Template argument deduction guides generate an entry in the Clang AST at global scope; ignore * Class constructors marked with constexpr generate a global instance; ignore. Pick-to: 6.4 Change-Id: I0cbee1d86baa705407cf2cf9e2d19b2e9b9f35d7 Reviewed-by: Luca Di Sera <luca.disera@qt.io>
* Port from qAsConst() to std::as_const()Marc Mutz2022-10-061-7/+7
| | | | | | | | | | | | | | | We've been requiring C++17 since Qt 6.0, and our qAsConst use finally starts to bother us (QTBUG-99313), so time to port away from it now. Since qAsConst has exactly the same semantics as std::as_const (down to rvalue treatment, constexpr'ness and noexcept'ness), there's really nothing more to it than a global search-and-replace. Task-number: QTBUG-99313 Change-Id: I234704ba429750ddee958a82f6c941d041da0653 Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io> Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* Port from container::count() and length() to size()Marc Mutz2022-10-061-1/+1
| | | | | | | | | | | | | | | | | | | | | | This is a semantic patch using ClangTidyTransformator as in qtbase/df9d882d41b741fef7c5beeddb0abe9d904443d8: auto QtContainerClass = anyOf( expr(hasType(cxxRecordDecl(isSameOrDerivedFrom(hasAnyName(classes))))).bind(o), expr(hasType(namedDecl(hasAnyName(<classes>)))).bind(o)); makeRule(cxxMemberCallExpr(on(QtContainerClass), callee(cxxMethodDecl(hasAnyName({"count", "length"), parameterCountIs(0))))), changeTo(cat(access(o, cat("size"), "()"))), cat("use 'size()' instead of 'count()/length()'")) a.k.a qt-port-to-std-compatible-api with config Scope: 'Container', with the extended set of container classes recognized. Change-Id: I95f6410e57a6a92b1cf91bbedfbe3d517cab6b44 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Kai Koehne <kai.koehne@qt.io> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
* QDoc: Remove setDesignable/setScriptable from [Qml]PropertyNodeLuca Di Sera2022-09-011-18/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Properties in the Qt property system can be, among other things, "designable" and "scriptable". A property that is "designable", that is, has the `DESIGNABLE` attribute, which is by default true, will generally be visible in some of Qt's GUI editor, such as Qt Designer. A property that is "scriptable", that is, has the `SCRIPTABLE` attribute, which is by default true, will generally be accessible by scripting engines (e.g QML engine). QDoc represents properties as the `PropertyNode` and `QmlPropertyNode` classes. During the parsing phase, in `clangcodeparser`, property declarations are parsed to generate correspective `Node`s that represent them, to allow the documentation of such elements. During this process, the `DESIGNABLE` attribute and the `SCRIPTABLE` attribute are taken into account and their "value" is stored into the produced property node. Nonetheless, the state of the attribute is never accessed during a QDoc execution, as we don't show information about "designability" and "scriptability" to the user. It is currently unknown if that information could be useful to the user, such that we should show it in the output documentation or if it could be used to discern between branching paths with regards to generating the property documentation itself. At the current time, nothing of the sort is done, so that any code related to those two attributes is to be considered dead. Hence, `PropertyNode::setDesignable`, `PropertyNode::setScriptable` and `QmlPropertyNode::setDesignable` were removed. The internal members of `PropertyNode`, `m_designable` and `m_scriptable`, and `QmlPropertyNode`, `m_designable`, were removed as they are now unused. A usage of `PropertyNode::m_designable` and `PropertyNode::m_scriptable` was removed in the implementation of `PropertyNode::setOverriddenFrom`, where the members where set based on the base property that the `PropertyNode` was overriding. Furthermore, `PropertyNode::designableDefault`, which was intended to represent the default value of the `DESIGNABLE` attribute for a property, was removed as it was unused. The code in `ClangCodeParser` that took care of setting the "DESIGNABLE" and "SCRIPTABLE" attribute was removed as a consequence of the other removals. Change-Id: I36cce8e3dd91af99dd6773160fd44b596762a49e Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* Use QT_DISABLE_DEPRECATED_UP_TO instead of QT_DISABLE_DEPRECATED_BEFOREIvan Solovev2022-08-231-1/+1
| | | | | | | Task-number: QTBUG-104944 Change-Id: I91efbdf9fb48ca3c6ed36960065a63c4a90ae5bc Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io> Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
* qdoc: Store BINDABLE property members into PropertyNodeTopi Reinio2022-08-231-5/+6
| | | | | | | | | | | | | | | | | | | | QDoc already recognized the BINDABLE attribute of Q_PROPERTY but did not store the name of the associated member. Store it in the list of a PropertyNode's access functions. This information will be useful later when deciding on whether to generate a warning for missing member functions; functions that are associated with properties can be left undocumented if the property itself is documented. Add a static helper function PropertyNode that returns the names of property access function roles. This is used when writing the access functions into an .index file. Convert access function-related enums to enum classes. Change-Id: Idd59622a965895883acf3ae297297ba3f3cca20e Reviewed-by: Luca Di Sera <luca.disera@qt.io>
* Use SPDX license identifiersLucie Gérard2022-05-191-38/+2
| | | | | | | | | | | Replace the current license disclaimer in files by a SPDX-License-Identifier. Files that have to be modified by hand are modified. License files are organized under LICENSES directory. Task-number: QTBUG-67283 Change-Id: I5335388c0472b0ee554234fc7eca60769e504660 Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
* qdoc: ClangCodeParser: Consider ref-qualifiers when searching for nodesTopi Reinio2022-03-281-0/+5
| | | | | | | | | | | findNodeForCursor() did not consider ref-qualifiers when comparing the signatures of FunctionNode candidates. This resulted in ref-qualified overloads to be masked by other overloads in certain cases. Pick-to: 6.3 Fixes: QTBUG-101461 Change-Id: Iac02d0840339c605cdc5915f25066fe0f39ae780 Reviewed-by: Luca Di Sera <luca.disera@qt.io>
* tools: do not rely on transitive includesFabian Kosmale2022-03-181-0/+2
| | | | | Change-Id: Ib78f984827988a39f56c4423eae40c67797549ea Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
* qdoc: Avoid clang warning about possibly missing commaKai Köhne2022-01-071-1/+1
| | | | | | | | | | Fixes clangcodeparser.cpp:1219:10: warning: suspicious concatenation of string literals in an array initialization; did you mean to separate the elements with a comma? [-Werror,-Wstring-concatenation] Pick-to: 6.2 6.3 Change-Id: Ifc5cb20b0f7f99d3851809b06a00551aa493a1b1 Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* qdoc: Fix heap-use-after-free and memory leak issuesTopi Reinio2021-11-061-1/+3
| | | | | | | | | | | | | | | | | | | | | | | Some of the created nodes appear multiple times in QDoc's node tree. This caused issues with address sanitizer during deletion of the tree: Nodes were checked for their parent() node, and the parent node might have been deleted already. Implement a cleanup function that removes all children that do not report *this* node as their parent from the list of children - after this, the tree can be safely deleted by destroying the root node. Fix memory leak issues; a couple of potential leaks in ClangCodeParser caused by not freeing resources in all cases, and DocBookGenerator leaking a QFile instance per each generated file. Pick-to: 6.2 Fixes: QTBUG-97627 Change-Id: If279b55ee24dc1b7291951ef11b7a26276df167c Reviewed-by: Luca Di Sera <luca.disera@qt.io> Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* qdoc: Teach Config::getCanonicalPathList() to read include pathsTopi Reinio2021-10-081-28/+8
| | | | | | | | | | | | | | | | | | | | | Include paths must be canonicalized for them to be correct. Previously, the ClangCodeParser did this step, but it was done in relation to the current working directory (cwd), and at that point cwd is the directory of the main (top-level) qdocconf file - if includepaths variable was used in another included config file and contained relative paths, this produced incorrect results. As Config already knowns how to canonicalize paths, teach it to consider the common prefixes associated with include paths. As config variables store their location, we can produce absolute paths reliably in all situations. Document the includepaths and the associated moduleheader variables. Fixes: QTBUG-97034 Pick-to: 6.2 Change-Id: Iecf68e3cb09ced732f7a05270441da046e8df8d8 Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* Identify files with the same name in the projectChen Bin2021-09-031-4/+10
| | | | | | | | | | | | | | If multiple subprojects of a subdirectory project have files with the same name, QDoc will not recognize them properly. It replaces the previous file path with the later identified file. And the contents of the tmpHeader file in the clang_parseTranslationUnit2 function don't contain all files of the same name. Fixes: QTBUG-95981 Pick-to: 6.2 Change-Id: Ic65f568ea89a6933c155a36f7f374627bff13555 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* qdoc: Query the compiler for system and framework include paths on macOSTopi Reinio2021-06-141-1/+9
| | | | | | | | | | | | | | Depending on the version, libclang is not able to resolve the system include paths on macOS; Fetch the include paths from the compiler by calling 'clang++ -E -x c++ - -v', parsing the output, and passing them as additional arguments when parsing the sources. Note that this requires the correct version of the compiler to be available under PATH. Fixes: QTBUG-94365 Change-Id: Iaa1b9869d3be0b4fcb8df00b47bb43a80032aa02 Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* qdoc: Fix MSVC warning C4267Kai Köhne2021-06-011-2/+2
| | | | | | | | | Fixes qdoc\clangcodeparser.cpp(1652): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data Pick-to: 6.1 Change-Id: I2a123415ef61f1427690ae798cbe658895e2e668 Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* QDoc: Code cleanupPaul Wicking2021-05-191-8/+8
| | | | | | | | | | | | | * Unify members; use s_ or m_ prefix instead of _ suffix. * Remove unnecessary member that duplicates content in base class. * Add [[nodiscard]] annotations where applicable. * Add overloads to virtual methods that have been extended with parameters with default values. * Make single argument ctors explicit. * Remove semi-colon from namespace declaration. Change-Id: Ie1ff39079722b81ba6754f945a898dc9b335bbae Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* Doc: Improve \deprecated commandPaul Wicking2021-05-101-44/+38
| | | | | | | | | | | | | | | | | | | | | | This change allows users to specify an optional parameter to the \deprecated command to record which version something was deprecated. It also allows for free text descriptions. These descriptions become the first paragraph of the resulting documentation. Usage: \deprecated \deprecated [6.2] \deprecated [6.2] Use QFoo() instead. \deprecated Use QFoo() instead. [ChangeLog][qdoc] QDoc now lets you record the version something is deprecated and suggest replacements with the \deprecated command. Task-number: QTBUG-58249 Change-Id: I27081627132b2f8ea3dd7d48ded8e37213366074 Reviewed-by: Topi Reiniö <topi.reinio@qt.io> Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* QDoc: Code cleanupPaul Wicking2021-05-031-51/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Use multiple arguments for QStrings instead of calling .arg() multiple times. * Define trivial constructor/destructor '= default' instead of adding empty implementations. * Remove unreachable code. * Prefer ranged-based for loops. * Initialize with auto from static_cast<>() and new. * Simplify expressions. * Prefer "QList::empty()" over "QList::size() > 0". * Remove unused method. * Return qsizetype instead of int to avoid narrowing conversion. * Remove unused include. * Remove unreachable return statement. * Prefer raw string literals over escaped regexes. * Initialize struct members. * Make variables used as const refs const refs. * Use std::move instead of passing const ref in ctor. * Drop redundant 'virtual' from methods marked 'override'. * Make local copies that arent ever modified const refs to avoid copying. * Turn for-loop into std::any_of. * Made single-argument constructor explicit. * Don't shadow variable names from outer scope if not necessary. * Remove const at top level that does not improve const correctness. * Update copyright notice for affected classes. Task-number: QTBUG-71176 Change-Id: Ia41e5b947b72f594b60d189b6b0ff68587c3afb9 Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* qdoc: Correctly handle const property typesTopi Reinio2021-03-191-12/+20
| | | | | | | | | | | The property type defined in Q_PROPERTY may contain the const qualifier. Store the qualifier and make the code a bit more robust against ill-formatted property declarations. Pick-to: 6.0 6.1 Fixes: QTBUG-91990 Change-Id: I6b06e4c8af8bb9dec3c467c6e19d9987b8340110 Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* qdoc: Enable C++20 supportTopi Reinio2020-11-021-1/+1
| | | | | | | | | | | Some public API features are conditionally enabled if the compiler supports C++20; enable this in QDoc as well when initializing libclang. Change-Id: I58fd8a62497de08da97ea28fc7a28811d91dd12e Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Paul Wicking <paul.wicking@qt.io> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
* qdoc: Fix handling of \fn signatures with unnamed parametersTopi Reinio2020-10-271-15/+14
| | | | | | | | | | | | | | | | A misplaced 'i++' caused an error where names of documented parameters were shifted around if one or more of the parameters were unnamed. Fixing the above uncovered issues with handling of \fn commands with [tag] argument; improve and simplify related code. Finally, avoid redundant space characters when generating signatures with unnamed parameters or in 'All Members' page where parameter names are omitted. Fixes: QTBUG-87855 Change-Id: I526c89c10c66572b8c71106660f43346a4751e4e Reviewed-by: Paul Wicking <paul.wicking@qt.io>