summaryrefslogtreecommitdiffstats
path: root/src/qdoc
diff options
context:
space:
mode:
Diffstat (limited to 'src/qdoc')
-rw-r--r--src/qdoc/cppcodemarker.cpp15
-rw-r--r--src/qdoc/cppcodeparser.cpp46
-rw-r--r--src/qdoc/cppcodeparser.h2
-rw-r--r--src/qdoc/generator.cpp22
-rw-r--r--src/qdoc/htmlgenerator.cpp2
-rw-r--r--src/qdoc/main.cpp5
-rw-r--r--src/qdoc/node.cpp33
-rw-r--r--src/qdoc/node.h18
-rw-r--r--src/qdoc/qdocindexfiles.cpp20
-rw-r--r--src/qdoc/qdoctagfiles.cpp10
-rw-r--r--src/qdoc/tokenizer.cpp2
-rw-r--r--src/qdoc/tokenizer.h3
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,