diff options
author | Luca Di Sera <luca.disera@qt.io> | 2023-01-13 14:34:15 +0100 |
---|---|---|
committer | Luca Di Sera <luca.disera@qt.io> | 2023-01-26 14:40:28 +0100 |
commit | 5358c553c106b3d2bd92ac3cf442eb625a16e76a (patch) | |
tree | a4873ca62c86a52d05202a38a8d6fb1b23a25327 /src/qdoc/clangcodeparser.cpp | |
parent | cd66158a60306850b39ba36486adefdea44a4b05 (diff) | |
download | qttools-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.cpp | 36 |
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( |