Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
cppcodemarker.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
5
6#include "access.h"
7#include "enumnode.h"
8#include "functionnode.h"
9#include "genustypes.h"
10#include "namespacenode.h"
11#include "propertynode.h"
14#include "text.h"
15#include "tree.h"
16#include "typedefnode.h"
17#include "variablenode.h"
18
19#include <QtCore/qdebug.h>
20#include <QtCore/qregularexpression.h>
21
23
24using namespace Qt::StringLiterals;
25
26/*!
27 \internal
28
29 Returns a marked-up representation of a single template parameter
30 with proper type markup for link generation.
31
32 Types (in non-type parameters and initializers) are wrapped with
33 \c{<@type>} tags so the HTML generator can create hyperlinks to
34 documented types.
35*/
36QString CppCodeMarker::formatTemplateParameter(const RelaxedTemplateParameter &param)
37{
38 QString result;
39 const auto &decl = param.valued_declaration;
40
41 if (param.template_declaration)
42 result += formatTemplateDeclStorage(*param.template_declaration, TemplateFormat::SingleLine) + ' '_L1;
43
44 // TODO: RelaxedTemplateParameter doesn't preserve whether the original
45 // declaration used 'class' or 'typename'. This would require parser changes.
46 switch (param.kind) {
47 case RelaxedTemplateParameter::Kind::TypeTemplateParameter:
48 result += "typename"_L1;
49 break;
51 if (!decl.type.empty())
52 result += typified(QString::fromStdString(decl.type), false);
53 break;
54 case RelaxedTemplateParameter::Kind::TemplateTemplateParameter:
55 result += "typename"_L1;
56 break;
57 }
58
59 if (param.is_parameter_pack)
60 result += "..."_L1;
61
62 if (!decl.name.empty()) {
63 if (!result.isEmpty() && !result.endsWith(' '_L1))
64 result += ' '_L1;
65 result += protect(QString::fromStdString(decl.name));
66 }
67
68 if (!decl.initializer.empty()) {
69 result += " = "_L1;
72 result += typified(QString::fromStdString(decl.initializer), false);
73 } else {
74 result += protect(QString::fromStdString(decl.initializer));
75 }
76 }
77
78 return result;
79}
80
81/*!
82 \internal
83
84 Returns a marked-up representation of a template declaration storage,
85 handling the common case for both top-level and nested (template template
86 parameter) declarations.
87
88 When \a format is MultiLine, parameters are formatted one per line with
89 indentation. Nested template declarations (called from formatTemplateParameter)
90 are always single-line.
91
92 This helper formats the core \c{template <...>} content without wrapper tags
93 or requires clause. The caller (formatTemplateDecl) handles those for
94 top-level declarations.
95
96 \sa formatTemplateParameter()
97*/
98QString CppCodeMarker::formatTemplateDeclStorage(const TemplateDeclarationStorage &templateDecl,
99 TemplateFormat format)
100{
101 const bool multiline = (format == TemplateFormat::MultiLine);
102
103 QString result = "template &lt;"_L1;
104
105 if (multiline)
106 result += '\n'_L1;
107
108 bool first = true;
109 for (const auto &param : templateDecl.parameters) {
110 if (param.sfinae_constraint)
111 continue;
112 if (!first)
113 result += multiline ? ",\n"_L1 : ", "_L1;
114 if (multiline)
115 result += " "_L1; // indentation for multiline format
116
117 result += formatTemplateParameter(param);
118 first = false;
119 }
120
121 if (multiline)
122 result += '\n'_L1;
123
124 result += "&gt;"_L1;
125
126 return result;
127}
128
129/*!
130 Returns a marked-up representation of the template declaration suitable
131 for synopsis output. For declarations above the multiline threshold,
132 a multiline format is used for improved readability.
133
134 Types within template parameters (non-type parameter types and default
135 value initializers) are wrapped with \c{<@type>} tags to enable link
136 generation to documented types.
137*/
138QString CppCodeMarker::formatTemplateDecl(const RelaxedTemplateDeclaration *templateDecl)
139{
140 const bool multiline = templateDecl->visibleParameterCount() > QDoc::MultilineTemplateParamThreshold;
141 const auto format = multiline ? TemplateFormat::MultiLine : TemplateFormat::SingleLine;
142
143 QString content = formatTemplateDeclStorage(*templateDecl, format);
144
145 QString result;
146 if (multiline)
147 result = "<@template-block>"_L1;
148
149 result += content;
150
151 if (templateDecl->requires_clause && !templateDecl->requires_clause->empty())
152 result += " requires "_L1 + protect(QString::fromStdString(*templateDecl->requires_clause));
153
154 if (multiline)
155 result += '\n'_L1 + "</@template-block>"_L1;
156 else
157 result += ' '_L1;
158
159 return result;
160}
161
162/*!
163 Returns \c true.
164 */
165bool CppCodeMarker::recognizeCode(const QString & /* code */)
166{
167 return true;
168}
169
170/*!
171 Returns \c true if \a ext is any of a list of file extensions
172 for the C++ language.
173 */
174bool CppCodeMarker::recognizeExtension(const QString &extension)
175{
176 QByteArray ext = extension.toLatin1();
177 return ext == "c" || ext == "c++" || ext == "qdoc" || ext == "qtt" || ext == "qtx"
178 || ext == "cc" || ext == "cpp" || ext == "cxx" || ext == "ch" || ext == "h"
179 || ext == "h++" || ext == "hh" || ext == "hpp" || ext == "hxx";
180}
181
182/*!
183 Returns \c true if \a lang is either "c" or "cpp".
184 */
185bool CppCodeMarker::recognizeLanguage(const QString &lang)
186{
187 return lang == QLatin1String("c") || lang == QLatin1String("cpp");
188}
189
190/*!
191 Returns the type of atom used to represent C++ code in the documentation.
192*/
193Atom::AtomType CppCodeMarker::atomType() const
194{
195 return Atom::Code;
196}
197
198QString CppCodeMarker::markedUpCode(const QString &code, const Node *relative,
199 const Location &location)
200{
201 return addMarkUp(code, relative, location);
202}
203
204QString CppCodeMarker::markedUpSynopsis(const Node *node, const Node * /* relative */,
205 Section::Style style)
206{
207 const int MaxEnumValues = 6;
208 const FunctionNode *func;
209 const VariableNode *variable;
210 const EnumNode *enume;
211 QString synopsis;
212 QString name;
213
214 name = taggedNode(node);
215 if (style != Section::Details)
216 name = linkTag(node, name);
217 name = "<@name>" + name + "</@name>";
218
219 if (style == Section::Details) {
220 if (!node->isRelatedNonmember() && !node->isProxyNode() && !node->parent()->name().isEmpty()
221 && !node->parent()->isHeader() && !node->isProperty() && !node->isQmlNode()) {
222 name.prepend(taggedNode(node->parent()) + "::");
223 }
224 }
225
226 switch (node->nodeType()) {
228 case NodeType::Class:
229 case NodeType::Struct:
230 case NodeType::Union:
231 synopsis = Node::nodeTypeString(node->nodeType());
232 synopsis += QLatin1Char(' ') + name;
233 break;
235 func = (const FunctionNode *)node;
236 if (style == Section::Details) {
237 if (auto templateDecl = node->templateDecl())
238 synopsis = formatTemplateDecl(&*templateDecl);
239 }
240 if (style != Section::AllMembers && !func->returnType().isEmpty())
241 synopsis += typified(func->returnTypeString(), true);
242 synopsis += name;
243 if (!func->isMacroWithoutParams()) {
244 synopsis += QLatin1Char('(');
245 if (!func->parameters().isEmpty()) {
246 const Parameters &parameters = func->parameters();
247 for (int i = 0; i < parameters.count(); ++i) {
248 if (i > 0)
249 synopsis += ", ";
250 const Parameter &param = parameters.at(i);
251 QString name = param.name();
252 QString type = param.type();
253 QString value = param.defaultValue();
254 qsizetype insertPos = param.nameInsertionPoint();
255 if (insertPos >= 0 && style != Section::AllMembers && !name.isEmpty()) {
256 // Inside-out declarator: name goes inside the type.
257 synopsis += typified(type.left(insertPos), false);
258 synopsis += "<@param>" + protect(name) + "</@param>";
259 synopsis += typified(type.mid(insertPos), false);
260 } else {
261 bool trailingSpace = style != Section::AllMembers && !name.isEmpty();
262 synopsis += typified(type, trailingSpace);
263 if (style != Section::AllMembers && !name.isEmpty())
264 synopsis += "<@param>" + protect(name) + "</@param>";
265 }
266 if (style != Section::AllMembers && !value.isEmpty())
267 synopsis += " = " + protect(value);
268 }
269 }
270 synopsis += QLatin1Char(')');
271 }
272 if (func->isConst())
273 synopsis += " const";
274
275 if (style == Section::Summary || style == Section::Accessors) {
276 if (!func->isNonvirtual())
277 synopsis.prepend("virtual ");
278 if (func->isFinal())
279 synopsis.append(" final");
280 if (func->isOverride())
281 synopsis.append(" override");
282 if (func->isPureVirtual())
283 synopsis.append(" = 0");
284 if (func->isRef())
285 synopsis.append(" &");
286 else if (func->isRefRef())
287 synopsis.append(" &&");
288 } else if (style == Section::AllMembers) {
289 if (!func->returnType().isEmpty() && func->returnType() != "void")
290 synopsis += " : " + typified(func->returnTypeString());
291 } else {
292 if (func->isRef())
293 synopsis.append(" &");
294 else if (func->isRefRef())
295 synopsis.append(" &&");
296 if (const auto &req = func->trailingRequiresClause(); req && !req->isEmpty())
297 synopsis.append(" requires " + protect(*req));
298 }
299 break;
300 case NodeType::Enum:
301 enume = static_cast<const EnumNode *>(node);
302 synopsis = "enum";
303 if (enume->isScoped())
304 synopsis += " class";
305 if (!enume->isAnonymous())
306 synopsis += " %1"_L1.arg(name);
307 else if (style != Section::Details)
308 synopsis = linkTag(node, synopsis); // Unnamed enum: Make `enum` a link to details
309 if (style == Section::Summary) {
310 synopsis += " { ";
311
312 QStringList documentedItems = enume->doc().enumItemNames();
313 if (documentedItems.isEmpty()) {
314 const auto &enumItems = enume->items();
315 for (const auto &item : enumItems)
316 documentedItems << item.name();
317 }
318 const QStringList omitItems = enume->doc().omitEnumItemNames();
319 for (const auto &item : omitItems)
320 documentedItems.removeAll(item);
321
322 if (documentedItems.size() > MaxEnumValues) {
323 // Take the last element and keep it safe, then elide the surplus.
324 const QString last = documentedItems.last();
325 documentedItems = documentedItems.mid(0, MaxEnumValues - 1);
326 documentedItems += "&hellip;";
327 documentedItems += last;
328 }
329 synopsis += documentedItems.join(QLatin1String(", "));
330
331 if (!documentedItems.isEmpty())
332 synopsis += QLatin1Char(' ');
333 synopsis += QLatin1Char('}');
334 }
335 break;
337 if (style == Section::Details) {
338 if (auto templateDecl = node->templateDecl())
339 synopsis += formatTemplateDecl(&*templateDecl);
340 }
341 synopsis += name;
342 break;
344 if (static_cast<const TypedefNode *>(node)->associatedEnum())
345 synopsis = "flags ";
346 synopsis += name;
347 break;
348 case NodeType::Property: {
349 auto property = static_cast<const PropertyNode *>(node);
350 synopsis = name + " : " + typified(property->qualifiedDataType());
351 break;
352 }
354 auto property = static_cast<const QmlPropertyNode *>(node);
355 synopsis = name + " : " + typified(property->dataType());
356 break;
357 }
358 case NodeType::Variable:
359 variable = static_cast<const VariableNode *>(node);
360 if (style == Section::AllMembers) {
361 synopsis = name + " : " + typified(variable->dataType());
362 } else {
363 synopsis = typified(variable->leftType(), true) + name + protect(variable->rightType());
364 }
365 break;
366 default:
367 synopsis = std::move(name);
368 }
369
370 QString extra = CodeMarker::extraSynopsis(node, style);
371 if (!extra.isEmpty()) {
372 extra.prepend(u"<@extra>"_s);
373 extra.append(u"</@extra> "_s);
374 }
375
376 return extra + synopsis;
377}
378
379/*!
380 */
381QString CppCodeMarker::markedUpQmlItem(const Node *node, bool summary)
382{
383 QString name = taggedQmlNode(node);
384 QString synopsis;
385
386 if (summary) {
387 name = linkTag(node, name);
388 } else if (node->isQmlProperty()) {
389 const auto *pn = static_cast<const QmlPropertyNode *>(node);
390 if (pn->isAttached())
391 name.prepend(pn->element() + QLatin1Char('.'));
392 }
393 name = "<@name>" + name + "</@name>";
394 if (node->isQmlProperty()) {
395 const auto *pn = static_cast<const QmlPropertyNode *>(node);
396 synopsis = name + " : " + typified(pn->dataType());
397 } else if (node->isFunction(Genus::QML)) {
398 const auto *func = static_cast<const FunctionNode *>(node);
399 if (!func->returnType().isEmpty())
400 synopsis = typified(func->returnTypeString(), true) + name;
401 else
402 synopsis = name;
403 synopsis += QLatin1Char('(');
404 if (!func->parameters().isEmpty()) {
405 const Parameters &parameters = func->parameters();
406 for (int i = 0; i < parameters.count(); ++i) {
407 if (i > 0)
408 synopsis += ", ";
409 QString name = parameters.at(i).name();
410 QString type = parameters.at(i).type();
411 QString paramName;
412 if (!name.isEmpty()) {
413 synopsis += typified(type, true);
414 paramName = std::move(name);
415 } else {
416 paramName = std::move(type);
417 }
418 synopsis += "<@param>" + protect(paramName) + "</@param>";
419 }
420 }
421 synopsis += QLatin1Char(')');
422 } else {
423 synopsis = std::move(name);
424 }
425
426 QString extra = CodeMarker::extraSynopsis(node, summary ? Section::Summary : Section::Details);
427 if (!extra.isEmpty()) {
428 extra.prepend(u" <@extra>"_s);
429 extra.append(u"</@extra>"_s);
430 }
431
432 return synopsis + extra;
433}
434
435QString CppCodeMarker::markedUpName(const Node *node)
436{
437 QString name = linkTag(node, taggedNode(node));
438 if (node->isFunction() && !node->isMacro())
439 name += "()";
440 return name;
441}
442
443QString CppCodeMarker::markedUpEnumValue(const QString &enumValue, const Node *relative)
444{
445 const auto *node = relative->parent();
446
447 const NativeEnum *nativeEnum{nullptr};
448 if (auto *ne_if = dynamic_cast<const NativeEnumInterface *>(relative))
449 nativeEnum = ne_if->nativeEnum();
450
451 if (nativeEnum && nativeEnum->enumNode()
452 && !enumValue.startsWith("%1."_L1.arg(nativeEnum->prefix())))
453 return "%1<@op>.</@op>%2"_L1.arg(nativeEnum->prefix(), enumValue);
454
455 // Respect existing prefixes in \value arguments of \qmlenum topic
456 if (relative->isEnumType(Genus::QML)
457 && enumValue.section(' ', 0, 0).contains('.'_L1)) {
458 return "<@op>%1</@op>"_L1.arg(enumValue);
459 }
460
461 if (!relative->isEnumType())
462 return enumValue;
463
464 QStringList parts;
465 while (!node->isHeader() && node->parent()) {
466 parts.prepend(markedUpName(node));
467 if (node->parent() == relative || node->parent()->name().isEmpty())
468 break;
469 node = node->parent();
470 }
471 if (static_cast<const EnumNode *>(relative)->isScoped())
472 parts.append(relative->name());
473
474 parts.append(enumValue);
475 const auto &delim = (relative->genus() == Genus::QML) ? "."_L1 : "::"_L1;
476 return parts.join("<@op>%1</@op>"_L1.arg(delim));
477}
478
479QString CppCodeMarker::addMarkUp(const QString &in, const Node * /* relative */,
480 const Location & /* location */)
481{
482 static QSet<QString> types{
483 QLatin1String("bool"), QLatin1String("char"), QLatin1String("double"),
484 QLatin1String("float"), QLatin1String("int"), QLatin1String("long"),
485 QLatin1String("short"), QLatin1String("signed"), QLatin1String("unsigned"),
486 QLatin1String("uint"), QLatin1String("ulong"), QLatin1String("ushort"),
487 QLatin1String("uchar"), QLatin1String("void"), QLatin1String("qlonglong"),
488 QLatin1String("qulonglong"), QLatin1String("qint"), QLatin1String("qint8"),
489 QLatin1String("qint16"), QLatin1String("qint32"), QLatin1String("qint64"),
490 QLatin1String("quint"), QLatin1String("quint8"), QLatin1String("quint16"),
491 QLatin1String("quint32"), QLatin1String("quint64"), QLatin1String("qreal"),
492 QLatin1String("cond")
493 };
494
495 static QSet<QString> keywords{
496 QLatin1String("and"), QLatin1String("and_eq"), QLatin1String("asm"), QLatin1String("auto"),
497 QLatin1String("bitand"), QLatin1String("bitor"), QLatin1String("break"),
498 QLatin1String("case"), QLatin1String("catch"), QLatin1String("class"),
499 QLatin1String("compl"), QLatin1String("const"), QLatin1String("const_cast"),
500 QLatin1String("continue"), QLatin1String("default"), QLatin1String("delete"),
501 QLatin1String("do"), QLatin1String("dynamic_cast"), QLatin1String("else"),
502 QLatin1String("enum"), QLatin1String("explicit"), QLatin1String("export"),
503 QLatin1String("extern"), QLatin1String("false"), QLatin1String("for"),
504 QLatin1String("friend"), QLatin1String("goto"), QLatin1String("if"),
505 QLatin1String("include"), QLatin1String("inline"), QLatin1String("monitor"),
506 QLatin1String("mutable"), QLatin1String("namespace"), QLatin1String("new"),
507 QLatin1String("not"), QLatin1String("not_eq"), QLatin1String("operator"),
508 QLatin1String("or"), QLatin1String("or_eq"), QLatin1String("private"),
509 QLatin1String("protected"), QLatin1String("public"), QLatin1String("register"),
510 QLatin1String("reinterpret_cast"), QLatin1String("return"), QLatin1String("sizeof"),
511 QLatin1String("static"), QLatin1String("static_cast"), QLatin1String("struct"),
512 QLatin1String("switch"), QLatin1String("template"), QLatin1String("this"),
513 QLatin1String("throw"), QLatin1String("true"), QLatin1String("try"),
514 QLatin1String("typedef"), QLatin1String("typeid"), QLatin1String("typename"),
515 QLatin1String("union"), QLatin1String("using"), QLatin1String("virtual"),
516 QLatin1String("volatile"), QLatin1String("wchar_t"), QLatin1String("while"),
517 QLatin1String("xor"), QLatin1String("xor_eq"), QLatin1String("synchronized"),
518 // Qt specific
519 QLatin1String("signals"), QLatin1String("slots"), QLatin1String("emit")
520 };
521
522 QString code = in;
523 QString out;
524 QStringView text;
525 int braceDepth = 0;
526 int parenDepth = 0;
527 int i = 0;
528 int start = 0;
529 int finish = 0;
530 QChar ch;
531 static const QRegularExpression classRegExp(QRegularExpression::anchoredPattern("Qt?(?:[A-Z3]+[a-z][A-Za-z]*|t)"));
532 static const QRegularExpression functionRegExp(QRegularExpression::anchoredPattern("q([A-Z][a-z]+)+"));
533 static const QRegularExpression findFunctionRegExp(QStringLiteral("^\\s*\\‍("));
534 bool atEOF = false;
535
536 auto readChar = [&]() {
537 if (i < code.size())
538 ch = code[i++];
539 else
540 atEOF = true;
541 };
542
543 readChar();
544 while (!atEOF) {
545 QString tag;
546 bool target = false;
547
548 if (ch.isLetter() || ch == '_') {
549 QString ident;
550 do {
551 ident += ch;
552 finish = i;
553 readChar();
554 } while (!atEOF && (ch.isLetterOrNumber() || ch == '_'));
555
556 if (classRegExp.match(ident).hasMatch()) {
557 tag = QStringLiteral("type");
558 } else if (functionRegExp.match(ident).hasMatch()) {
559 tag = QStringLiteral("func");
560 target = true;
561 } else if (types.contains(ident)) {
562 tag = QStringLiteral("type");
563 } else if (keywords.contains(ident)) {
564 tag = QStringLiteral("keyword");
565 } else if (braceDepth == 0 && parenDepth == 0) {
566 if (code.indexOf(findFunctionRegExp, i - 1) == i - 1)
567 tag = QStringLiteral("func");
568 target = true;
569 }
570 } else if (ch.isDigit()) {
571 do {
572 finish = i;
573 readChar();
574 } while (!atEOF && (ch.isLetterOrNumber() || ch == '.' || ch == '\''));
575 tag = QStringLiteral("number");
576 } else {
577 switch (ch.unicode()) {
578 case '+':
579 case '-':
580 case '!':
581 case '%':
582 case '^':
583 case '&':
584 case '*':
585 case ',':
586 case '.':
587 case '<':
588 case '=':
589 case '>':
590 case '?':
591 case '[':
592 case ']':
593 case '|':
594 case '~':
595 finish = i;
596 readChar();
597 tag = QStringLiteral("op");
598 break;
599 case '"':
600 finish = i;
601 readChar();
602
603 while (!atEOF && ch != '"') {
604 if (ch == '\\')
605 readChar();
606 readChar();
607 }
608 finish = i;
609 readChar();
610 tag = QStringLiteral("string");
611 break;
612 case '#':
613 finish = i;
614 readChar();
615 while (!atEOF && ch != '\n') {
616 if (ch == '\\')
617 readChar();
618 finish = i;
619 readChar();
620 }
621 tag = QStringLiteral("preprocessor");
622 break;
623 case '\'':
624 finish = i;
625 readChar();
626
627 while (!atEOF && ch != '\'') {
628 if (ch == '\\')
629 readChar();
630 readChar();
631 }
632 finish = i;
633 readChar();
634 tag = QStringLiteral("char");
635 break;
636 case '(':
637 finish = i;
638 readChar();
639 ++parenDepth;
640 break;
641 case ')':
642 finish = i;
643 readChar();
644 --parenDepth;
645 break;
646 case ':':
647 finish = i;
648 readChar();
649 if (!atEOF && ch == ':') {
650 finish = i;
651 readChar();
652 tag = QStringLiteral("op");
653 }
654 break;
655 case '/':
656 finish = i;
657 readChar();
658 if (!atEOF && ch == '/') {
659 do {
660 finish = i;
661 readChar();
662 } while (!atEOF && ch != '\n');
663 tag = QStringLiteral("comment");
664 } else if (ch == '*') {
665 bool metAster = false;
666 bool metAsterSlash = false;
667
668 finish = i;
669 readChar();
670
671 while (!metAsterSlash) {
672 if (atEOF)
673 break;
674 if (ch == '*')
675 metAster = true;
676 else if (metAster && ch == '/')
677 metAsterSlash = true;
678 else
679 metAster = false;
680 finish = i;
681 readChar();
682 }
683 tag = QStringLiteral("comment");
684 } else {
685 tag = QStringLiteral("op");
686 }
687 break;
688 case '{':
689 finish = i;
690 readChar();
691 braceDepth++;
692 break;
693 case '}':
694 finish = i;
695 readChar();
696 braceDepth--;
697 break;
698 default:
699 finish = i;
700 readChar();
701 }
702 }
703
704 text = QStringView{code}.mid(start, finish - start);
705 start = finish;
706
707 if (!tag.isEmpty()) {
708 out += QStringLiteral("<@");
709 out += tag;
710 if (target) {
711 out += QStringLiteral(" target=\"");
712 out += text;
713 out += QStringLiteral("()\"");
714 }
715 out += QStringLiteral(">");
716 }
717
718 appendProtectedString(&out, text);
719
720 if (!tag.isEmpty()) {
721 out += QStringLiteral("</@");
722 out += tag;
723 out += QStringLiteral(">");
724 }
725 }
726
727 if (start < code.size()) {
728 appendProtectedString(&out, QStringView{code}.mid(start));
729 }
730
731 return out;
732}
733
734QT_END_NAMESPACE
The Atom class is the fundamental unit for representing documents internally.
Definition atom.h:19
AtomType
\value AnnotatedList \value AutoLink \value BaseName \value BriefLeft \value BriefRight \value C \val...
Definition atom.h:21
@ Code
Definition atom.h:31
bool isScoped() const
Definition enumnode.h:33
This node is used to represent any kind of function being documented.
bool isMacroWithoutParams() const
bool isOverride() const
const Parameters & parameters() const
bool isPureVirtual() const override
bool isRef() const
bool isNonvirtual() const
bool isConst() const
bool isRefRef() const
bool isFinal() const
The Location class provides a way to mark a location in a file.
Definition location.h:20
Interface implemented by Node subclasses that can refer to a C++ enum.
Definition nativeenum.h:28
virtual const NativeEnum * nativeEnum() const =0
Encapsulates information about native (C++) enum values.
Definition nativeenum.h:14
The Parameter class describes one function parameter.
Definition parameter.h:14
A class for containing the elements of one documentation section.
Definition sections.h:17
@ Summary
Definition sections.h:19
@ Details
Definition sections.h:19
@ Accessors
Definition sections.h:19
@ AllMembers
Definition sections.h:19
NodeType
Definition genustypes.h:150
constexpr std::size_t MultilineTemplateParamThreshold
Combined button and popup list for selecting options.
The Node class is the base class for all the nodes in QDoc's parse tree.
const Doc & doc() const
Returns a reference to the node's Doc data member.
Definition node.h:235
bool isQmlNode() const
Returns true if this node's Genus value is QML.
Definition node.h:119
bool isEnumType(Genus g) const
Definition node.h:97
bool isHeader() const
Returns true if the node type is HeaderFile.
Definition node.h:105
NodeType nodeType() const override
Returns this node's type.
Definition node.h:82
virtual bool isMacro() const
returns true if either FunctionNode::isMacroWithParams() or FunctionNode::isMacroWithoutParams() retu...
Definition node.h:147
bool isEnumType() const
Returns true if the node type is Enum.
Definition node.h:93
Aggregate * parent() const
Returns the node's parent pointer.
Definition node.h:208
bool isProxyNode() const
Returns true if the node type is Proxy.
Definition node.h:113
bool isFunction(Genus g=Genus::DontCare) const
Returns true if this is a FunctionNode and its Genus is set to g.
Definition node.h:100
bool isProperty() const
Returns true if the node type is Property.
Definition node.h:112
bool isRelatedNonmember() const
Returns true if this is a related nonmember of something.
Definition node.h:122
bool isQmlProperty() const
Returns true if the node type is QmlProperty.
Definition node.h:120
A class for parsing and managing a function parameter list.
Definition main.cpp:28
bool isEmpty() const
Definition parameters.h:32
const Parameter & at(int i) const
Definition parameters.h:36
int count() const
Definition parameters.h:34
std::size_t visibleParameterCount() const
Returns the number of template parameters that are visible in rendered output — SFINAE-annotated para...
ValuedDeclaration valued_declaration