summaryrefslogtreecommitdiff
path: root/src/qdoc/clangcodeparser.cpp
diff options
context:
space:
mode:
authorLuca Di Sera <luca.disera@qt.io>2023-01-13 14:34:15 +0100
committerLuca Di Sera <luca.disera@qt.io>2023-01-26 14:40:28 +0100
commit5358c553c106b3d2bd92ac3cf442eb625a16e76a (patch)
treea4873ca62c86a52d05202a38a8d6fb1b23a25327 /src/qdoc/clangcodeparser.cpp
parentcd66158a60306850b39ba36486adefdea44a4b05 (diff)
downloadqttools-5358c553c106b3d2bd92ac3cf442eb625a16e76a.tar.gz
QDoc: Use clang's C++ API to recognize copy/move assignment operators
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>
Diffstat (limited to 'src/qdoc/clangcodeparser.cpp')
-rw-r--r--src/qdoc/clangcodeparser.cpp36
1 files changed, 5 insertions, 31 deletions
diff --git a/src/qdoc/clangcodeparser.cpp b/src/qdoc/clangcodeparser.cpp
index 0681fe6a4..30eb32929 100644
--- a/src/qdoc/clangcodeparser.cpp
+++ b/src/qdoc/clangcodeparser.cpp
@@ -979,6 +979,11 @@ void ClangVisitor::processFunction(FunctionNode *fn, CXCursor cursor)
(conversion_declaration && conversion_declaration->isExplicit())
) fn->markExplicit();
+ const clang::CXXMethodDecl* method_declaration = llvm::dyn_cast<const clang::CXXMethodDecl>(function_declaration);
+
+ if (method_declaration && method_declaration->isCopyAssignmentOperator()) fn->setMetaness(FunctionNode::CAssign);
+ else if (method_declaration && method_declaration->isMoveAssignmentOperator()) fn->setMetaness(FunctionNode::MAssign);
+
const clang::FunctionType* function_type = function_declaration->getFunctionType();
const clang::FunctionProtoType* function_prototype = static_cast<const clang::FunctionProtoType*>(function_type);
@@ -1012,39 +1017,8 @@ void ClangVisitor::processFunction(FunctionNode *fn, CXCursor cursor)
parameters.clear();
parameters.reserve(numArg);
- // TODO: [clang16-required][unsound-code][bug-ridden]
- // The following code that sets the metaness of the currently
- // processed function node incorrect in multiple ways with regards
- // to the specification of move/copy constructors/assignment
- // operators.
- //
- // For example, it doesn't correctly allow for qualifiers nor does
- // it correctly respect the argument disposition.
- //
- // It was previously bugged and still present a series of bugs
- // such as being able to misidentify constructors types.
- //
- // A by-specification implementation in our currently used
- // libclang is not particularly feasible due to the required
- // complexity and is preferred to be avoided.
- //
- // To solve the issue, we pushed a series of patches to upstream
- // llvm to expose some of the C++ API methods that would
- // trivialize the following code.
- //
- // Those methods will be available on LLVM 16, which is currently
- // expected for January 2023.
- // When LLVM 16 comes out and we upgrade to it, the following code
- // should be fixed and the minimum required version of libclang
- // for QDoc should be updated.
for (int i = 0; i < numArg; ++i) {
CXType argType = clang_getArgType(funcType, i);
- if ((kind == CXCursor_CXXMethod) && (fn->name() == QLatin1String("operator="))) {
- if (argType.kind == CXType_RValueReference)
- fn->setMetaness(FunctionNode::MAssign);
- else if (argType.kind == CXType_LValueReference)
- fn->setMetaness(FunctionNode::CAssign);
- }
parameters.append(adjustTypeName(fromCXString(clang_getTypeSpelling(argType))));
if (argType.kind == CXType_Typedef || argType.kind == CXType_Elaborated) {
parameters.last().setCanonicalType(fromCXString(