diff options
Diffstat (limited to 'src/qdoc')
-rw-r--r-- | src/qdoc/cppcodemarker.cpp | 15 | ||||
-rw-r--r-- | src/qdoc/cppcodeparser.cpp | 46 | ||||
-rw-r--r-- | src/qdoc/cppcodeparser.h | 2 | ||||
-rw-r--r-- | src/qdoc/generator.cpp | 22 | ||||
-rw-r--r-- | src/qdoc/htmlgenerator.cpp | 2 | ||||
-rw-r--r-- | src/qdoc/main.cpp | 5 | ||||
-rw-r--r-- | src/qdoc/node.cpp | 33 | ||||
-rw-r--r-- | src/qdoc/node.h | 18 | ||||
-rw-r--r-- | src/qdoc/qdocindexfiles.cpp | 20 | ||||
-rw-r--r-- | src/qdoc/qdoctagfiles.cpp | 10 | ||||
-rw-r--r-- | src/qdoc/tokenizer.cpp | 2 | ||||
-rw-r--r-- | src/qdoc/tokenizer.h | 3 |
12 files changed, 150 insertions, 28 deletions
diff --git a/src/qdoc/cppcodemarker.cpp b/src/qdoc/cppcodemarker.cpp index b0e4e823d..0f413c7f5 100644 --- a/src/qdoc/cppcodemarker.cpp +++ b/src/qdoc/cppcodemarker.cpp @@ -179,8 +179,14 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node, if (style == Summary || style == Accessors) { if (func->virtualness() != FunctionNode::NonVirtual) synopsis.prepend("virtual "); + if (func->isFinal()) + synopsis.append(" final"); if (func->virtualness() == FunctionNode::PureVirtual) synopsis.append(" = 0"); + else if (func->isDeleted()) + synopsis.append(" = delete"); + else if (func->isDefaulted()) + synopsis.append(" = default"); } else if (style == Subpage) { if (!func->returnType().isEmpty() && func->returnType() != "void") @@ -190,8 +196,13 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node, QStringList bracketed; if (func->isStatic()) { bracketed += "static"; - } - else if (func->virtualness() != FunctionNode::NonVirtual) { + } else if (func->isDeleted()) { + bracketed += "delete"; + } else if (func->isDefaulted()) { + bracketed += "default"; + } else if (func->virtualness() != FunctionNode::NonVirtual) { + if (func->isFinal()) + bracketed += "final"; if (func->virtualness() == FunctionNode::PureVirtual) bracketed += "pure"; bracketed += "virtual"; diff --git a/src/qdoc/cppcodeparser.cpp b/src/qdoc/cppcodeparser.cpp index 0405cc2c2..03b74b83e 100644 --- a/src/qdoc/cppcodeparser.cpp +++ b/src/qdoc/cppcodeparser.cpp @@ -1179,7 +1179,7 @@ bool CppCodeParser::matchTemplateHeader() return matchTemplateAngles(); } -bool CppCodeParser::matchDataType(CodeChunk *dataType, QString *var) +bool CppCodeParser::matchDataType(CodeChunk *dataType, QString *var, bool qProp) { /* This code is really hard to follow... sorry. The loop is there to match @@ -1255,7 +1255,7 @@ bool CppCodeParser::matchDataType(CodeChunk *dataType, QString *var) } while (match(Tok_Ampersand) || match(Tok_Aster) || match(Tok_const) || - match(Tok_Caret)) + match(Tok_Caret) || match(Tok_Ellipsis)) dataType->append(previousLexeme()); if (match(Tok_LeftParenAster)) { @@ -1305,6 +1305,10 @@ bool CppCodeParser::matchDataType(CodeChunk *dataType, QString *var) if (varComment.exactMatch(previousLexeme())) *var = varComment.cap(1); } + else if (qProp && (match(Tok_default) || match(Tok_final))) { + // Hack to make 'default' and 'final' work again in Q_PROPERTY + *var = previousLexeme(); + } } if (tok == Tok_LeftBracket) { @@ -1512,7 +1516,7 @@ bool CppCodeParser::matchFunctionDecl(Aggregate *parent, } if (parent && (tok == Tok_Semicolon || tok == Tok_LeftBracket || - tok == Tok_Colon) + tok == Tok_Colon || tok == Tok_Equal) && access != Node::Private) { if (tok == Tok_LeftBracket) { returnType.appendHotspot(); @@ -1528,7 +1532,7 @@ bool CppCodeParser::matchFunctionDecl(Aggregate *parent, return false; } } - else if (tok == Tok_Colon) { + else if (tok == Tok_Colon || tok == Tok_Equal) { returnType.appendHotspot(); while (tok != Tok_Semicolon && tok != Tok_Eoi) { @@ -1570,11 +1574,18 @@ bool CppCodeParser::matchFunctionDecl(Aggregate *parent, // look for const bool matchedConst = match(Tok_const); + bool matchFinal = match(Tok_final); - // look for 0 indicating pure virtual - if (match(Tok_Equal) && match(Tok_Number)) - virtuality = FunctionNode::PureVirtual; - + bool isDeleted = false; + bool isDefaulted = false; + if (match(Tok_Equal)) { + if (match(Tok_Number)) // look for 0 indicating pure virtual + virtuality = FunctionNode::PureVirtual; + else if (match(Tok_delete)) + isDeleted = true; + else if (match(Tok_default)) + isDefaulted = true; + } // look for colon indicating ctors which must be skipped if (match(Tok_Colon)) { while (tok != Tok_LeftBrace && tok != Tok_Eoi) @@ -1644,6 +1655,9 @@ bool CppCodeParser::matchFunctionDecl(Aggregate *parent, func->setStatic(matched_static); func->setConst(matchedConst); func->setVirtualness(virtuality); + func->setIsDeleted(isDeleted); + func->setIsDefaulted(isDefaulted); + func->setFinal(matchFinal); if (isQPrivateSignal) func->setPrivateSignal(); if (!pvect.isEmpty()) { @@ -1732,6 +1746,9 @@ bool CppCodeParser::matchClassDecl(Aggregate *parent, } } } + + const QString className = previousLexeme(); + match(Tok_final); // ignore C++11 final class-virt-specifier if (tok != Tok_Colon && tok != Tok_LeftBrace) return false; @@ -1739,7 +1756,7 @@ bool CppCodeParser::matchClassDecl(Aggregate *parent, So far, so good. We have 'class Foo {' or 'class Foo :'. This is enough to recognize a class definition. */ - ClassNode *classe = new ClassNode(parent, previousLexeme()); + ClassNode *classe = new ClassNode(parent, className); classe->setAccess(access); classe->setLocation(location()); if (compat) @@ -1931,8 +1948,15 @@ bool CppCodeParser::matchEnumDecl(Aggregate *parent) if (!match(Tok_enum)) return false; + if (tok == Tok_struct || tok == Tok_class) + readToken(); // ignore C++11 struct or class attribute if (match(Tok_Ident)) name = previousLexeme(); + if (match(Tok_Colon)) { // ignore C++11 enum-base + CodeChunk dataType; + if (!matchDataType(&dataType)) + return false; + } if (tok != Tok_LeftBrace) return false; @@ -1995,7 +2019,7 @@ bool CppCodeParser::matchProperty(Aggregate *parent) QString name; CodeChunk dataType; - if (!matchDataType(&dataType, &name)) + if (!matchDataType(&dataType, &name, true)) return false; PropertyNode *property = new PropertyNode(parent, name); @@ -2004,7 +2028,7 @@ bool CppCodeParser::matchProperty(Aggregate *parent) property->setDataType(dataType.toString()); while (tok != Tok_RightParen && tok != Tok_Eoi) { - if (!match(Tok_Ident)) + if (!match(Tok_Ident) && !match(Tok_default) && !match(Tok_final)) return false; QString key = previousLexeme(); QString value; diff --git a/src/qdoc/cppcodeparser.h b/src/qdoc/cppcodeparser.h index ec0448232..7c110d2bb 100644 --- a/src/qdoc/cppcodeparser.h +++ b/src/qdoc/cppcodeparser.h @@ -117,7 +117,7 @@ protected: bool matchModuleQualifier(QString& name); bool matchTemplateAngles(CodeChunk *type = 0); bool matchTemplateHeader(); - bool matchDataType(CodeChunk *type, QString *var = 0); + bool matchDataType(CodeChunk *type, QString *var = 0, bool qProp = false); bool matchParameter(QVector<Parameter>& pvect, bool& isQPrivateSignal); bool matchFunctionDecl(Aggregate *parent, QStringList *parentPathPtr, diff --git a/src/qdoc/generator.cpp b/src/qdoc/generator.cpp index 81ad2a94b..c8c2ecefd 100644 --- a/src/qdoc/generator.cpp +++ b/src/qdoc/generator.cpp @@ -752,8 +752,26 @@ void Generator::generateBody(const Node *node, CodeMarker *marker) } } if (node->doc().isEmpty()) { - if (!node->isWrapper() && !quiet && !node->isReimplemented()) { // ### might be unnecessary - node->location().warning(tr("No documentation for '%1'").arg(node->plainFullName())); + /* + Test for special function, like a destructor or copy constructor, + that has no documentation. + */ + if (node->type() == Node::Function) { + const FunctionNode* func = static_cast<const FunctionNode*>(node); + if (func->isDtor()) { + Text text; + text << "Destroys the instance of "; + text << func->parent()->name() << "."; + if (func->isVirtual()) + text << " The destructor is virtual."; + generateText(text, node, marker); + } + else if (!node->isWrapper() && !quiet && !node->isReimplemented()) { + node->location().warning(tr("No documentation for '%1'").arg(node->plainSignature())); + } + } + else if (!node->isWrapper() && !quiet && !node->isReimplemented()) { + node->location().warning(tr("No documentation for '%1'").arg(node->plainSignature())); } } else { diff --git a/src/qdoc/htmlgenerator.cpp b/src/qdoc/htmlgenerator.cpp index 6b43cc653..74b93b14d 100644 --- a/src/qdoc/htmlgenerator.cpp +++ b/src/qdoc/htmlgenerator.cpp @@ -3218,7 +3218,7 @@ void HtmlGenerator::generateList(const Node* relative, CodeMarker* marker, const comment where the topic is \group, \module, \qmlmodule, or \jsmodule */ - if (!relative || !relative->isCollectionNode()) { + if (relative && !relative->isCollectionNode()) { relative->doc().location().warning(tr("\\generatelist {%1} is only allowed in \\group, " "\\module, \\qmlmodule, and \\jsmodule comments.").arg(selector)); return; diff --git a/src/qdoc/main.cpp b/src/qdoc/main.cpp index 8ebebda79..500a085cc 100644 --- a/src/qdoc/main.cpp +++ b/src/qdoc/main.cpp @@ -728,8 +728,11 @@ int main(int argc, char **argv) Generator::setQDocPass(Generator::Prepare); if (parser.isSet(generateOption)) Generator::setQDocPass(Generator::Generate); - if (parser.isSet(singleExecOption)) + if (parser.isSet(singleExecOption)) { Generator::setSingleExec(); + if (parser.isSet(indexDirOption)) + qDebug() << "WARNING: -indexdir option ignored: Index files are not used in -single-exec mode."; + } if (parser.isSet(writeQaPagesOption)) Generator::setWriteQaPages(); if (parser.isSet(logProgressOption)) diff --git a/src/qdoc/node.cpp b/src/qdoc/node.cpp index 9740f984f..d91d473ce 100644 --- a/src/qdoc/node.cpp +++ b/src/qdoc/node.cpp @@ -165,6 +165,29 @@ QString Node::plainFullName(const Node* relative) const } /*! + Constructs and returns the node's fully qualified signature + by recursively ascending the parent links and prepending each + parent name + "::" to the plain signature. The return type is + not included. + */ +QString Node::plainSignature() const +{ + if (name_.isEmpty()) + return QLatin1String("global"); + + QString fullName; + const Node* node = this; + while (node) { + fullName.prepend(node->signature(false, true)); + if (node->parent()->name().isEmpty()) + break; + fullName.prepend(QLatin1String("::")); + node = node->parent(); + } + return fullName; +} + +/*! Constructs and returns this node's full name. */ QString Node::fullName(const Node* relative) const @@ -1951,6 +1974,9 @@ FunctionNode::FunctionNode(Aggregate *parent, const QString& name) attached_(false), privateSignal_(false), overload_(false), + isDeleted_(false), + isDefaulted_(false), + isFinal_(false), reimplementedFrom_(0) { setGenus(Node::CPP); @@ -1974,6 +2000,9 @@ FunctionNode::FunctionNode(NodeType type, Aggregate *parent, const QString& name attached_(attached), privateSignal_(false), overload_(false), + isDeleted_(false), + isDefaulted_(false), + isFinal_(false), reimplementedFrom_(0) { setGenus(Node::QML); @@ -2133,10 +2162,10 @@ QStringList FunctionNode::reconstructParameters(bool values) const is true, the default values of the parameters are included, if present. */ -QString FunctionNode::signature(bool values) const +QString FunctionNode::signature(bool values, bool noReturnType) const { QString s; - if (!returnType().isEmpty()) + if (!noReturnType && !returnType().isEmpty()) s = returnType() + QLatin1Char(' '); s += name() + QLatin1Char('('); QStringList reconstructedParameters = reconstructParameters(values); diff --git a/src/qdoc/node.h b/src/qdoc/node.h index 945bc2187..9df3dd70a 100644 --- a/src/qdoc/node.h +++ b/src/qdoc/node.h @@ -159,7 +159,9 @@ public: QString plainName() const; QString plainFullName(const Node* relative = 0) const; + QString plainSignature() const; QString fullName(const Node* relative=0) const; + virtual QString signature(bool , bool ) const { return plainName(); } const QString& fileNameBase() const { return fileNameBase_; } bool hasFileNameBase() const { return !fileNameBase_.isEmpty(); } @@ -894,6 +896,8 @@ public: bool isOverload() const { return overload_; } bool isReimplemented() const Q_DECL_OVERRIDE { return reimplemented_; } bool isFunction() const Q_DECL_OVERRIDE { return true; } + bool isDtor() const { return (metaness_ == Dtor); } + bool isVirtual() const { return (virtualness_ == NormalVirtual); } virtual bool isQmlSignal() const Q_DECL_OVERRIDE { return (type() == Node::QmlSignal) && (genus() == Node::QML); } @@ -926,7 +930,7 @@ public: bool hasActiveAssociatedProperty() const; QStringList reconstructParameters(bool values = false) const; - QString signature(bool values = false) const; + virtual QString signature(bool values, bool noReturnType = false) const; virtual QString element() const Q_DECL_OVERRIDE { return parent()->name(); } virtual bool isAttached() const Q_DECL_OVERRIDE { return attached_; } virtual bool isQtQuickNode() const Q_DECL_OVERRIDE { return parent()->isQtQuickNode(); } @@ -945,6 +949,15 @@ public: void debug() const; + bool isDeleted() const { return isDeleted_; } + void setIsDeleted(bool b) { isDeleted_ = b; } + + bool isDefaulted() const { return isDefaulted_; } + void setIsDefaulted(bool b) { isDefaulted_ = b; } + + void setFinal(bool b) { isFinal_ = b; } + bool isFinal() const { return isFinal_; } + private: void addAssociatedProperty(PropertyNode* property); @@ -961,6 +974,9 @@ private: bool attached_: 1; bool privateSignal_: 1; bool overload_ : 1; + bool isDeleted_ : 1; + bool isDefaulted_ : 1; + bool isFinal_ : 1; unsigned char overloadNumber_; QVector<Parameter> parameters_; const FunctionNode* reimplementedFrom_; diff --git a/src/qdoc/qdocindexfiles.cpp b/src/qdoc/qdocindexfiles.cpp index b3bf064fa..f588638fe 100644 --- a/src/qdoc/qdocindexfiles.cpp +++ b/src/qdoc/qdocindexfiles.cpp @@ -523,6 +523,9 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader, functionNode->setMetaness(meta); functionNode->setConst(attributes.value(QLatin1String("const")) == QLatin1String("true")); functionNode->setStatic(attributes.value(QLatin1String("static")) == QLatin1String("true")); + functionNode->setIsDeleted(attributes.value(QLatin1String("delete")) == QLatin1String("true")); + functionNode->setIsDefaulted(attributes.value(QLatin1String("default")) == QLatin1String("true")); + functionNode->setFinal(attributes.value(QLatin1String("final")) == QLatin1String("true")); if (attributes.value(QLatin1String("overload")) == QLatin1String("true")) { functionNode->setOverloadFlag(true); functionNode->setOverloadNumber(attributes.value(QLatin1String("overload-number")).toUInt()); @@ -1245,6 +1248,9 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer, writer.writeAttribute("const", functionNode->isConst()?"true":"false"); writer.writeAttribute("static", functionNode->isStatic()?"true":"false"); writer.writeAttribute("overload", functionNode->isOverload()?"true":"false"); + writer.writeAttribute("delete", functionNode->isDeleted() ? "true" : "false"); + writer.writeAttribute("default", functionNode->isDefaulted() ? "true" : "false"); + writer.writeAttribute("final", functionNode->isFinal() ? "true" : "false"); if (functionNode->isOverload()) writer.writeAttribute("overload-number", QString::number(functionNode->overloadNumber())); if (functionNode->relates()) { @@ -1267,9 +1273,17 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer, Note: The "signature" attribute is written to the index file, but it is not read back in. Is that ok? */ - QString signature = functionNode->signature(); + QString signature = functionNode->signature(false); if (functionNode->isConst()) signature += " const"; + if (functionNode->isFinal()) + signature += " final"; + if (functionNode->virtualness() == FunctionNode::PureVirtual) + signature += " = 0"; + else if (functionNode->isDeleted()) + signature += " = delete"; + else if (functionNode->isDefaulted()) + signature += " = default"; writer.writeAttribute("signature", signature); for (int i = 0; i < functionNode->parameters().size(); ++i) { @@ -1483,9 +1497,9 @@ bool compareNodes(const Node* n1, const Node* n2) else if (f1->isConst() > f2->isConst()) return false; - if (f1->signature() < f2->signature()) + if (f1->signature(false) < f2->signature(false)) return true; - else if (f1->signature() > f2->signature()) + else if (f1->signature(false) > f2->signature(false)) return false; } diff --git a/src/qdoc/qdoctagfiles.cpp b/src/qdoc/qdoctagfiles.cpp index 1210ac7c3..cc5b30c8e 100644 --- a/src/qdoc/qdoctagfiles.cpp +++ b/src/qdoc/qdoctagfiles.cpp @@ -271,7 +271,7 @@ void QDocTagFiles::generateTagFileMembers(QXmlStreamWriter& writer, const Aggreg writer.writeAttribute("virtualness", "virtual"); break; case FunctionNode::PureVirtual: - writer.writeAttribute("virtual", "pure"); + writer.writeAttribute("virtualness", "pure"); break; default: break; @@ -287,12 +287,18 @@ void QDocTagFiles::generateTagFileMembers(QXmlStreamWriter& writer, const Aggreg QStringList pieces = gen_->fullDocumentLocation(node, false).split(QLatin1Char('#')); writer.writeTextElement("anchorfile", pieces[0]); writer.writeTextElement("anchor", pieces[1]); - QString signature = functionNode->signature(); + QString signature = functionNode->signature(false); signature = signature.mid(signature.indexOf(QChar('('))).trimmed(); if (functionNode->isConst()) signature += " const"; + if (functionNode->isFinal()) + signature += " final"; if (functionNode->virtualness() == FunctionNode::PureVirtual) signature += " = 0"; + else if (functionNode->isDeleted()) + signature += " = delete"; + else if (functionNode->isDefaulted()) + signature += " = default"; writer.writeTextElement("arglist", signature); } writer.writeEndElement(); // member diff --git a/src/qdoc/tokenizer.cpp b/src/qdoc/tokenizer.cpp index 987fff548..f723debe7 100644 --- a/src/qdoc/tokenizer.cpp +++ b/src/qdoc/tokenizer.cpp @@ -59,7 +59,7 @@ static const char *kwords[] = { "private", "protected", "public", "short", "signals", "signed", "slots", "static", "struct", "template", "typedef", "typename", "union", "unsigned", "using", "virtual", "void", "volatile", - "__int64", + "__int64", "default", "delete", "final", "Q_OBJECT", "Q_OVERRIDE", "Q_PROPERTY", diff --git a/src/qdoc/tokenizer.h b/src/qdoc/tokenizer.h index 41a3ffd93..2f293379f 100644 --- a/src/qdoc/tokenizer.h +++ b/src/qdoc/tokenizer.h @@ -66,7 +66,8 @@ enum { Tok_Eoi, Tok_Ampersand, Tok_Aster, Tok_Caret, Tok_LeftParen, Tok_public, Tok_short, Tok_signals, Tok_signed, Tok_slots, Tok_static, Tok_struct, Tok_template, Tok_typedef, Tok_typename, Tok_union, Tok_unsigned, Tok_using, Tok_virtual, - Tok_void, Tok_volatile, Tok_int64, Tok_Q_OBJECT, Tok_Q_OVERRIDE, + Tok_void, Tok_volatile, Tok_int64, Tok_default, Tok_delete, Tok_final, + Tok_Q_OBJECT, Tok_Q_OVERRIDE, Tok_Q_PROPERTY, Tok_Q_PRIVATE_PROPERTY, Tok_Q_DECLARE_SEQUENTIAL_ITERATOR, Tok_Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR, Tok_Q_DECLARE_ASSOCIATIVE_ITERATOR, |