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;
50 case RelaxedTemplateParameter::Kind::NonTypeTemplateParameter:
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 for (qsizetype i = 0; i < static_cast<qsizetype>(templateDecl.parameters.size()); ++i) {
109 if (i > 0)
110 result += multiline ? ",\n"_L1 : ", "_L1;
111 if (multiline)
112 result += " "_L1; // indentation for multiline format
113
114 result += formatTemplateParameter(templateDecl.parameters[i]);
115 }
116
117 if (multiline)
118 result += '\n'_L1;
119
120 result += "&gt;"_L1;
121
122 return result;
123}
124
125/*!
126 Returns a marked-up representation of the template declaration suitable
127 for synopsis output. For declarations above the multiline threshold,
128 a multiline format is used for improved readability.
129
130 Types within template parameters (non-type parameter types and default
131 value initializers) are wrapped with \c{<@type>} tags to enable link
132 generation to documented types.
133*/
134QString CppCodeMarker::formatTemplateDecl(const RelaxedTemplateDeclaration *templateDecl)
135{
136 const bool multiline = templateDecl->parameters.size() > QDoc::MultilineTemplateParamThreshold;
137 const auto format = multiline ? TemplateFormat::MultiLine : TemplateFormat::SingleLine;
138
139 QString content = formatTemplateDeclStorage(*templateDecl, format);
140
141 QString result;
142 if (multiline)
143 result = "<@template-block>"_L1;
144
145 result += content;
146
147 if (templateDecl->requires_clause && !templateDecl->requires_clause->empty())
148 result += " requires "_L1 + protect(QString::fromStdString(*templateDecl->requires_clause));
149
150 if (multiline)
151 result += '\n'_L1 + "</@template-block>"_L1;
152 else
153 result += ' '_L1;
154
155 return result;
156}
157
158/*!
159 Returns \c true.
160 */
161bool CppCodeMarker::recognizeCode(const QString & /* code */)
162{
163 return true;
164}
165
166/*!
167 Returns \c true if \a ext is any of a list of file extensions
168 for the C++ language.
169 */
170bool CppCodeMarker::recognizeExtension(const QString &extension)
171{
172 QByteArray ext = extension.toLatin1();
173 return ext == "c" || ext == "c++" || ext == "qdoc" || ext == "qtt" || ext == "qtx"
174 || ext == "cc" || ext == "cpp" || ext == "cxx" || ext == "ch" || ext == "h"
175 || ext == "h++" || ext == "hh" || ext == "hpp" || ext == "hxx";
176}
177
178/*!
179 Returns \c true if \a lang is either "c" or "cpp".
180 */
181bool CppCodeMarker::recognizeLanguage(const QString &lang)
182{
183 return lang == QLatin1String("c") || lang == QLatin1String("cpp");
184}
185
186/*!
187 Returns the type of atom used to represent C++ code in the documentation.
188*/
189Atom::AtomType CppCodeMarker::atomType() const
190{
191 return Atom::Code;
192}
193
194QString CppCodeMarker::markedUpCode(const QString &code, const Node *relative,
195 const Location &location)
196{
197 return addMarkUp(code, relative, location);
198}
199
200QString CppCodeMarker::markedUpSynopsis(const Node *node, const Node * /* relative */,
201 Section::Style style)
202{
203 const int MaxEnumValues = 6;
204 const FunctionNode *func;
205 const VariableNode *variable;
206 const EnumNode *enume;
207 QString synopsis;
208 QString name;
209
210 name = taggedNode(node);
211 if (style != Section::Details)
212 name = linkTag(node, name);
213 name = "<@name>" + name + "</@name>";
214
215 if (style == Section::Details) {
216 if (!node->isRelatedNonmember() && !node->isProxyNode() && !node->parent()->name().isEmpty()
217 && !node->parent()->isHeader() && !node->isProperty() && !node->isQmlNode()) {
218 name.prepend(taggedNode(node->parent()) + "::");
219 }
220 }
221
222 switch (node->nodeType()) {
224 case NodeType::Class:
225 case NodeType::Struct:
226 case NodeType::Union:
227 synopsis = Node::nodeTypeString(node->nodeType());
228 synopsis += QLatin1Char(' ') + name;
229 break;
231 func = (const FunctionNode *)node;
232 if (style == Section::Details) {
233 if (auto templateDecl = node->templateDecl())
234 synopsis = formatTemplateDecl(&*templateDecl);
235 }
236 if (style != Section::AllMembers && !func->returnType().isEmpty())
237 synopsis += typified(func->returnTypeString(), true);
238 synopsis += name;
239 if (!func->isMacroWithoutParams()) {
240 synopsis += QLatin1Char('(');
241 if (!func->parameters().isEmpty()) {
242 const Parameters &parameters = func->parameters();
243 for (int i = 0; i < parameters.count(); ++i) {
244 if (i > 0)
245 synopsis += ", ";
246 QString name = parameters.at(i).name();
247 QString type = parameters.at(i).type();
248 QString value = parameters.at(i).defaultValue();
249 bool trailingSpace = style != Section::AllMembers && !name.isEmpty();
250 synopsis += typified(type, trailingSpace);
251 if (style != Section::AllMembers && !name.isEmpty())
252 synopsis += "<@param>" + protect(name) + "</@param>";
253 if (style != Section::AllMembers && !value.isEmpty())
254 synopsis += " = " + protect(value);
255 }
256 }
257 synopsis += QLatin1Char(')');
258 }
259 if (func->isConst())
260 synopsis += " const";
261
262 if (style == Section::Summary || style == Section::Accessors) {
263 if (!func->isNonvirtual())
264 synopsis.prepend("virtual ");
265 if (func->isFinal())
266 synopsis.append(" final");
267 if (func->isOverride())
268 synopsis.append(" override");
269 if (func->isPureVirtual())
270 synopsis.append(" = 0");
271 if (func->isRef())
272 synopsis.append(" &");
273 else if (func->isRefRef())
274 synopsis.append(" &&");
275 } else if (style == Section::AllMembers) {
276 if (!func->returnType().isEmpty() && func->returnType() != "void")
277 synopsis += " : " + typified(func->returnTypeString());
278 } else {
279 if (func->isRef())
280 synopsis.append(" &");
281 else if (func->isRefRef())
282 synopsis.append(" &&");
283 if (const auto &req = func->trailingRequiresClause(); req && !req->isEmpty())
284 synopsis.append(" requires " + protect(*req));
285 }
286 break;
287 case NodeType::Enum:
288 enume = static_cast<const EnumNode *>(node);
289 synopsis = "enum";
290 if (enume->isScoped())
291 synopsis += " class";
292 if (!enume->isAnonymous())
293 synopsis += " %1"_L1.arg(name);
294 else if (style != Section::Details)
295 synopsis = linkTag(node, synopsis); // Unnamed enum: Make `enum` a link to details
296 if (style == Section::Summary) {
297 synopsis += " { ";
298
299 QStringList documentedItems = enume->doc().enumItemNames();
300 if (documentedItems.isEmpty()) {
301 const auto &enumItems = enume->items();
302 for (const auto &item : enumItems)
303 documentedItems << item.name();
304 }
305 const QStringList omitItems = enume->doc().omitEnumItemNames();
306 for (const auto &item : omitItems)
307 documentedItems.removeAll(item);
308
309 if (documentedItems.size() > MaxEnumValues) {
310 // Take the last element and keep it safe, then elide the surplus.
311 const QString last = documentedItems.last();
312 documentedItems = documentedItems.mid(0, MaxEnumValues - 1);
313 documentedItems += "&hellip;";
314 documentedItems += last;
315 }
316 synopsis += documentedItems.join(QLatin1String(", "));
317
318 if (!documentedItems.isEmpty())
319 synopsis += QLatin1Char(' ');
320 synopsis += QLatin1Char('}');
321 }
322 break;
324 if (style == Section::Details) {
325 if (auto templateDecl = node->templateDecl())
326 synopsis += formatTemplateDecl(&*templateDecl);
327 }
328 synopsis += name;
329 break;
331 if (static_cast<const TypedefNode *>(node)->associatedEnum())
332 synopsis = "flags ";
333 synopsis += name;
334 break;
335 case NodeType::Property: {
336 auto property = static_cast<const PropertyNode *>(node);
337 synopsis = name + " : " + typified(property->qualifiedDataType());
338 break;
339 }
341 auto property = static_cast<const QmlPropertyNode *>(node);
342 synopsis = name + " : " + typified(property->dataType());
343 break;
344 }
345 case NodeType::Variable:
346 variable = static_cast<const VariableNode *>(node);
347 if (style == Section::AllMembers) {
348 synopsis = name + " : " + typified(variable->dataType());
349 } else {
350 synopsis = typified(variable->leftType(), true) + name + protect(variable->rightType());
351 }
352 break;
353 default:
354 synopsis = std::move(name);
355 }
356
357 QString extra = CodeMarker::extraSynopsis(node, style);
358 if (!extra.isEmpty()) {
359 extra.prepend(u"<@extra>"_s);
360 extra.append(u"</@extra> "_s);
361 }
362
363 return extra + synopsis;
364}
365
366/*!
367 */
368QString CppCodeMarker::markedUpQmlItem(const Node *node, bool summary)
369{
370 QString name = taggedQmlNode(node);
371 QString synopsis;
372
373 if (summary) {
374 name = linkTag(node, name);
375 } else if (node->isQmlProperty()) {
376 const auto *pn = static_cast<const QmlPropertyNode *>(node);
377 if (pn->isAttached())
378 name.prepend(pn->element() + QLatin1Char('.'));
379 }
380 name = "<@name>" + name + "</@name>";
381 if (node->isQmlProperty()) {
382 const auto *pn = static_cast<const QmlPropertyNode *>(node);
383 synopsis = name + " : " + typified(pn->dataType());
384 } else if (node->isFunction(Genus::QML)) {
385 const auto *func = static_cast<const FunctionNode *>(node);
386 if (!func->returnType().isEmpty())
387 synopsis = typified(func->returnTypeString(), true) + name;
388 else
389 synopsis = name;
390 synopsis += QLatin1Char('(');
391 if (!func->parameters().isEmpty()) {
392 const Parameters &parameters = func->parameters();
393 for (int i = 0; i < parameters.count(); ++i) {
394 if (i > 0)
395 synopsis += ", ";
396 QString name = parameters.at(i).name();
397 QString type = parameters.at(i).type();
398 QString paramName;
399 if (!name.isEmpty()) {
400 synopsis += typified(type, true);
401 paramName = std::move(name);
402 } else {
403 paramName = std::move(type);
404 }
405 synopsis += "<@param>" + protect(paramName) + "</@param>";
406 }
407 }
408 synopsis += QLatin1Char(')');
409 } else {
410 synopsis = std::move(name);
411 }
412
413 QString extra = CodeMarker::extraSynopsis(node, summary ? Section::Summary : Section::Details);
414 if (!extra.isEmpty()) {
415 extra.prepend(u" <@extra>"_s);
416 extra.append(u"</@extra>"_s);
417 }
418
419 return synopsis + extra;
420}
421
422QString CppCodeMarker::markedUpName(const Node *node)
423{
424 QString name = linkTag(node, taggedNode(node));
425 if (node->isFunction() && !node->isMacro())
426 name += "()";
427 return name;
428}
429
430QString CppCodeMarker::markedUpEnumValue(const QString &enumValue, const Node *relative)
431{
432 const auto *node = relative->parent();
433
434 const NativeEnum *nativeEnum{nullptr};
435 if (auto *ne_if = dynamic_cast<const NativeEnumInterface *>(relative))
436 nativeEnum = ne_if->nativeEnum();
437
438 if (nativeEnum && nativeEnum->enumNode()
439 && !enumValue.startsWith("%1."_L1.arg(nativeEnum->prefix())))
440 return "%1<@op>.</@op>%2"_L1.arg(nativeEnum->prefix(), enumValue);
441
442 // Respect existing prefixes in \value arguments of \qmlenum topic
443 if (relative->isEnumType(Genus::QML)
444 && enumValue.section(' ', 0, 0).contains('.'_L1)) {
445 return "<@op>%1</@op>"_L1.arg(enumValue);
446 }
447
448 if (!relative->isEnumType())
449 return enumValue;
450
451 QStringList parts;
452 while (!node->isHeader() && node->parent()) {
453 parts.prepend(markedUpName(node));
454 if (node->parent() == relative || node->parent()->name().isEmpty())
455 break;
456 node = node->parent();
457 }
458 if (static_cast<const EnumNode *>(relative)->isScoped())
459 parts.append(relative->name());
460
461 parts.append(enumValue);
462 const auto &delim = (relative->genus() == Genus::QML) ? "."_L1 : "::"_L1;
463 return parts.join("<@op>%1</@op>"_L1.arg(delim));
464}
465
466QString CppCodeMarker::addMarkUp(const QString &in, const Node * /* relative */,
467 const Location & /* location */)
468{
469 static QSet<QString> types{
470 QLatin1String("bool"), QLatin1String("char"), QLatin1String("double"),
471 QLatin1String("float"), QLatin1String("int"), QLatin1String("long"),
472 QLatin1String("short"), QLatin1String("signed"), QLatin1String("unsigned"),
473 QLatin1String("uint"), QLatin1String("ulong"), QLatin1String("ushort"),
474 QLatin1String("uchar"), QLatin1String("void"), QLatin1String("qlonglong"),
475 QLatin1String("qulonglong"), QLatin1String("qint"), QLatin1String("qint8"),
476 QLatin1String("qint16"), QLatin1String("qint32"), QLatin1String("qint64"),
477 QLatin1String("quint"), QLatin1String("quint8"), QLatin1String("quint16"),
478 QLatin1String("quint32"), QLatin1String("quint64"), QLatin1String("qreal"),
479 QLatin1String("cond")
480 };
481
482 static QSet<QString> keywords{
483 QLatin1String("and"), QLatin1String("and_eq"), QLatin1String("asm"), QLatin1String("auto"),
484 QLatin1String("bitand"), QLatin1String("bitor"), QLatin1String("break"),
485 QLatin1String("case"), QLatin1String("catch"), QLatin1String("class"),
486 QLatin1String("compl"), QLatin1String("const"), QLatin1String("const_cast"),
487 QLatin1String("continue"), QLatin1String("default"), QLatin1String("delete"),
488 QLatin1String("do"), QLatin1String("dynamic_cast"), QLatin1String("else"),
489 QLatin1String("enum"), QLatin1String("explicit"), QLatin1String("export"),
490 QLatin1String("extern"), QLatin1String("false"), QLatin1String("for"),
491 QLatin1String("friend"), QLatin1String("goto"), QLatin1String("if"),
492 QLatin1String("include"), QLatin1String("inline"), QLatin1String("monitor"),
493 QLatin1String("mutable"), QLatin1String("namespace"), QLatin1String("new"),
494 QLatin1String("not"), QLatin1String("not_eq"), QLatin1String("operator"),
495 QLatin1String("or"), QLatin1String("or_eq"), QLatin1String("private"),
496 QLatin1String("protected"), QLatin1String("public"), QLatin1String("register"),
497 QLatin1String("reinterpret_cast"), QLatin1String("return"), QLatin1String("sizeof"),
498 QLatin1String("static"), QLatin1String("static_cast"), QLatin1String("struct"),
499 QLatin1String("switch"), QLatin1String("template"), QLatin1String("this"),
500 QLatin1String("throw"), QLatin1String("true"), QLatin1String("try"),
501 QLatin1String("typedef"), QLatin1String("typeid"), QLatin1String("typename"),
502 QLatin1String("union"), QLatin1String("using"), QLatin1String("virtual"),
503 QLatin1String("volatile"), QLatin1String("wchar_t"), QLatin1String("while"),
504 QLatin1String("xor"), QLatin1String("xor_eq"), QLatin1String("synchronized"),
505 // Qt specific
506 QLatin1String("signals"), QLatin1String("slots"), QLatin1String("emit")
507 };
508
509 QString code = in;
510 QString out;
511 QStringView text;
512 int braceDepth = 0;
513 int parenDepth = 0;
514 int i = 0;
515 int start = 0;
516 int finish = 0;
517 QChar ch;
518 static const QRegularExpression classRegExp(QRegularExpression::anchoredPattern("Qt?(?:[A-Z3]+[a-z][A-Za-z]*|t)"));
519 static const QRegularExpression functionRegExp(QRegularExpression::anchoredPattern("q([A-Z][a-z]+)+"));
520 static const QRegularExpression findFunctionRegExp(QStringLiteral("^\\s*\\‍("));
521 bool atEOF = false;
522
523 auto readChar = [&]() {
524 if (i < code.size())
525 ch = code[i++];
526 else
527 atEOF = true;
528 };
529
530 readChar();
531 while (!atEOF) {
532 QString tag;
533 bool target = false;
534
535 if (ch.isLetter() || ch == '_') {
536 QString ident;
537 do {
538 ident += ch;
539 finish = i;
540 readChar();
541 } while (!atEOF && (ch.isLetterOrNumber() || ch == '_'));
542
543 if (classRegExp.match(ident).hasMatch()) {
544 tag = QStringLiteral("type");
545 } else if (functionRegExp.match(ident).hasMatch()) {
546 tag = QStringLiteral("func");
547 target = true;
548 } else if (types.contains(ident)) {
549 tag = QStringLiteral("type");
550 } else if (keywords.contains(ident)) {
551 tag = QStringLiteral("keyword");
552 } else if (braceDepth == 0 && parenDepth == 0) {
553 if (code.indexOf(findFunctionRegExp, i - 1) == i - 1)
554 tag = QStringLiteral("func");
555 target = true;
556 }
557 } else if (ch.isDigit()) {
558 do {
559 finish = i;
560 readChar();
561 } while (!atEOF && (ch.isLetterOrNumber() || ch == '.' || ch == '\''));
562 tag = QStringLiteral("number");
563 } else {
564 switch (ch.unicode()) {
565 case '+':
566 case '-':
567 case '!':
568 case '%':
569 case '^':
570 case '&':
571 case '*':
572 case ',':
573 case '.':
574 case '<':
575 case '=':
576 case '>':
577 case '?':
578 case '[':
579 case ']':
580 case '|':
581 case '~':
582 finish = i;
583 readChar();
584 tag = QStringLiteral("op");
585 break;
586 case '"':
587 finish = i;
588 readChar();
589
590 while (!atEOF && ch != '"') {
591 if (ch == '\\')
592 readChar();
593 readChar();
594 }
595 finish = i;
596 readChar();
597 tag = QStringLiteral("string");
598 break;
599 case '#':
600 finish = i;
601 readChar();
602 while (!atEOF && ch != '\n') {
603 if (ch == '\\')
604 readChar();
605 finish = i;
606 readChar();
607 }
608 tag = QStringLiteral("preprocessor");
609 break;
610 case '\'':
611 finish = i;
612 readChar();
613
614 while (!atEOF && ch != '\'') {
615 if (ch == '\\')
616 readChar();
617 readChar();
618 }
619 finish = i;
620 readChar();
621 tag = QStringLiteral("char");
622 break;
623 case '(':
624 finish = i;
625 readChar();
626 ++parenDepth;
627 break;
628 case ')':
629 finish = i;
630 readChar();
631 --parenDepth;
632 break;
633 case ':':
634 finish = i;
635 readChar();
636 if (!atEOF && ch == ':') {
637 finish = i;
638 readChar();
639 tag = QStringLiteral("op");
640 }
641 break;
642 case '/':
643 finish = i;
644 readChar();
645 if (!atEOF && ch == '/') {
646 do {
647 finish = i;
648 readChar();
649 } while (!atEOF && ch != '\n');
650 tag = QStringLiteral("comment");
651 } else if (ch == '*') {
652 bool metAster = false;
653 bool metAsterSlash = false;
654
655 finish = i;
656 readChar();
657
658 while (!metAsterSlash) {
659 if (atEOF)
660 break;
661 if (ch == '*')
662 metAster = true;
663 else if (metAster && ch == '/')
664 metAsterSlash = true;
665 else
666 metAster = false;
667 finish = i;
668 readChar();
669 }
670 tag = QStringLiteral("comment");
671 } else {
672 tag = QStringLiteral("op");
673 }
674 break;
675 case '{':
676 finish = i;
677 readChar();
678 braceDepth++;
679 break;
680 case '}':
681 finish = i;
682 readChar();
683 braceDepth--;
684 break;
685 default:
686 finish = i;
687 readChar();
688 }
689 }
690
691 text = QStringView{code}.mid(start, finish - start);
692 start = finish;
693
694 if (!tag.isEmpty()) {
695 out += QStringLiteral("<@");
696 out += tag;
697 if (target) {
698 out += QStringLiteral(" target=\"");
699 out += text;
700 out += QStringLiteral("()\"");
701 }
702 out += QStringLiteral(">");
703 }
704
705 appendProtectedString(&out, text);
706
707 if (!tag.isEmpty()) {
708 out += QStringLiteral("</@");
709 out += tag;
710 out += QStringLiteral(">");
711 }
712 }
713
714 if (start < code.size()) {
715 appendProtectedString(&out, QStringView{code}.mid(start));
716 }
717
718 return out;
719}
720
721QT_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
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:70
const Parameter & at(int i) const
Definition parameters.h:74
int count() const
Definition parameters.h:72
ValuedDeclaration valued_declaration