summaryrefslogtreecommitdiff
path: root/src/qdoc/clangcodeparser.cpp
diff options
context:
space:
mode:
authorLuca Di Sera <luca.disera@qt.io>2023-01-13 13:12:21 +0100
committerLuca Di Sera <luca.disera@qt.io>2023-01-26 14:40:28 +0100
commitcd66158a60306850b39ba36486adefdea44a4b05 (patch)
tree6867bfd9d6120939bbfa9ceadd4be2a64cbb0a48 /src/qdoc/clangcodeparser.cpp
parente7a5008b856b36dc504745e1325c13e8e62ce0c1 (diff)
downloadqttools-cd66158a60306850b39ba36486adefdea44a4b05.tar.gz
QDoc: Use clang's C++ API to recognize copy/move constructors
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>
Diffstat (limited to 'src/qdoc/clangcodeparser.cpp')
-rw-r--r--src/qdoc/clangcodeparser.cpp39
1 files changed, 5 insertions, 34 deletions
diff --git a/src/qdoc/clangcodeparser.cpp b/src/qdoc/clangcodeparser.cpp
index eb11e7994..0681fe6a4 100644
--- a/src/qdoc/clangcodeparser.cpp
+++ b/src/qdoc/clangcodeparser.cpp
@@ -967,6 +967,10 @@ void ClangVisitor::processFunction(FunctionNode *fn, CXCursor cursor)
assert(function_declaration);
const clang::CXXConstructorDecl* constructor_declaration = llvm::dyn_cast<const clang::CXXConstructorDecl>(function_declaration);
+
+ if (constructor_declaration && constructor_declaration->isCopyConstructor()) fn->setMetaness(FunctionNode::CCtor);
+ else if (constructor_declaration && constructor_declaration->isMoveConstructor()) fn->setMetaness(FunctionNode::MCtor);
+
const clang::CXXConversionDecl* conversion_declaration = llvm::dyn_cast<const clang::CXXConversionDecl>(function_declaration);
if (function_declaration->isConstexpr()) fn->markConstexpr();
@@ -1035,40 +1039,7 @@ void ClangVisitor::processFunction(FunctionNode *fn, CXCursor cursor)
// for QDoc should be updated.
for (int i = 0; i < numArg; ++i) {
CXType argType = clang_getArgType(funcType, i);
- if (fn->isCtor()) {
- // TODO:KLUDGE: [temporary-hack]
- // The following is used to fix a very specific bug in the
- // way QDoc assigns the metaness of constructors.
- // It is nonetheless quite imperfect in its handling and
- // is only used as a temporary fix while LLVM 16 is not
- // available.
- //
- // This is expected to be removed as soon as LLVM 16 comes out.
- static auto remove_qualifiers = [](QString type_spelling) {
- // REMARK: While, generally, a type with
- // both qualifiers would be written "const volatile
- // T", clang accepts "volatile const T" too.
- //
- // Nonetheless, we do not handle that case as
- // libclang, when providing the spelling, currently
- // always writes the const-qualifier before the
- // volatile-qualifier.
- if (type_spelling.startsWith("const "))
- type_spelling.remove(0, QString("const ").size());
-
- if (type_spelling.startsWith("volatile "))
- type_spelling.remove(0, QString("volatile ").size());
-
- return type_spelling;
- };
-
- const QString type_spelling{remove_qualifiers(fromCXString(clang_getTypeSpelling(clang_getPointeeType(argType))))};
- if (type_spelling == fn->name()) {
- if (argType.kind == CXType_RValueReference) fn->setMetaness(FunctionNode::MCtor);
- else if (argType.kind == CXType_LValueReference) fn->setMetaness(FunctionNode::CCtor);
- }
-
- } else if ((kind == CXCursor_CXXMethod) && (fn->name() == QLatin1String("operator="))) {
+ if ((kind == CXCursor_CXXMethod) && (fn->name() == QLatin1String("operator="))) {
if (argType.kind == CXType_RValueReference)
fn->setMetaness(FunctionNode::MAssign);
else if (argType.kind == CXType_LValueReference)