summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2016-02-19 15:20:39 +0100
committerLiang Qi <liang.qi@theqtcompany.com>2016-02-19 15:26:41 +0000
commit863a6621d14caf67adcf3f30cb955a268765f0f1 (patch)
tree259e076b43ea65aec0284e0b2edad95b88f3f764
parent1735c0c7e68e754aee16aa24fbcd002b174f547e (diff)
Revert "qdoc: Remove creation of redundant function & variable nodes"
This reverts commit 18fe6a9a5eb4a1c2ce62cd64b42b6db5e581e152. Because we are changing the C++ parser to clang, we won't need this anymore. Task-number: QTBUG-48191 Change-Id: Iacf134ab91517a0eb3e28ea6bce41f74e3c957a0 Reviewed-by: Martin Smith <martin.smith@theqtcompany.com>
-rw-r--r--src/qdoc/cppcodeparser.cpp639
-rw-r--r--src/qdoc/cppcodeparser.h32
-rw-r--r--src/qdoc/generator.cpp2
-rw-r--r--src/qdoc/main.cpp6
-rw-r--r--src/qdoc/node.cpp107
-rw-r--r--src/qdoc/node.h166
-rw-r--r--src/qdoc/qdocdatabase.cpp24
-rw-r--r--src/qdoc/qdocdatabase.h6
-rw-r--r--src/qdoc/qdocindexfiles.cpp6
-rw-r--r--src/qdoc/qdoctagfiles.cpp2
-rw-r--r--src/qdoc/tokenizer.cpp9
-rw-r--r--src/qdoc/tokenizer.h4
-rw-r--r--src/qdoc/tree.cpp25
-rw-r--r--src/qdoc/tree.h4
14 files changed, 446 insertions, 586 deletions
diff --git a/src/qdoc/cppcodeparser.cpp b/src/qdoc/cppcodeparser.cpp
index 98800164f..0405cc2c2 100644
--- a/src/qdoc/cppcodeparser.cpp
+++ b/src/qdoc/cppcodeparser.cpp
@@ -316,80 +316,88 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc,
const QString& command,
const ArgLocPair& arg)
{
+ ExtraFuncData extra;
if (command == COMMAND_FN) {
- Declaration declData;
- if (!parseDeclaration(arg.first, declData)) {
- declData.clear();
- if (!parseDeclaration("void " + arg.first, declData)) {
- doc.startLocation().warning(tr("Invalid syntax in '\\%1'").arg(COMMAND_FN));
- return 0;
- }
+ QStringList parentPath;
+ FunctionNode *func = 0;
+ FunctionNode *clone = 0;
+
+ if (!makeFunctionNode(arg.first, &parentPath, &clone, extra) &&
+ !makeFunctionNode("void " + arg.first, &parentPath, &clone, extra)) {
+ doc.startLocation().warning(tr("Invalid syntax in '\\%1'").arg(COMMAND_FN));
}
- FunctionNode* func = qdb_->findFunctionNode(declData.parentPath_, declData);
- if (func == 0) {
- if (declData.parentPath_.isEmpty() && !lastPath_.isEmpty()) {
- func = qdb_->findFunctionNode(lastPath_, declData);
+ else {
+ func = qdb_->findFunctionNode(parentPath, clone);
+ if (func == 0) {
+ if (parentPath.isEmpty() && !lastPath_.isEmpty())
+ func = qdb_->findFunctionNode(lastPath_, clone);
}
- }
- /*
- If the node was not found, then search for it in the
- open C++ namespaces. We don't expect this search to
- be necessary often. Nor do we expect it to succeed
- very often.
- */
- if (func == 0)
- func = qdb_->findNodeInOpenNamespace(declData.parentPath_, declData);
-
- if (func == 0) {
- doc.location().warning(tr("Cannot find '%1' in '\\%2' %3")
- .arg(declData.name_ + "(...)")
- .arg(COMMAND_FN)
- .arg(arg.first),
- tr("I cannot find any function of that name with the "
- "specified signature. Make sure that the signature "
- "is identical to the declaration, including 'const' "
- "qualifiers."));
- }
- else
- lastPath_ = declData.parentPath_;
- if (func) {
- func->borrowParameterNames(declData);
- func->setParentPath(declData.parentPath_);
+
+ /*
+ If the node was not found, then search for it in the
+ open C++ namespaces. We don't expect this search to
+ be necessary often. Nor do we expect it to succeed
+ very often.
+ */
+ if (func == 0)
+ func = qdb_->findNodeInOpenNamespace(parentPath, clone);
+
+ if (func == 0) {
+ doc.location().warning(tr("Cannot find '%1' in '\\%2' %3")
+ .arg(clone->name() + "(...)")
+ .arg(COMMAND_FN)
+ .arg(arg.first),
+ tr("I cannot find any function of that name with the "
+ "specified signature. Make sure that the signature "
+ "is identical to the declaration, including 'const' "
+ "qualifiers."));
+ }
+ else
+ lastPath_ = parentPath;
+ if (func) {
+ func->borrowParameterNames(clone);
+ func->setParentPath(clone->parentPath());
+ }
+ delete clone;
}
return func;
}
else if (command == COMMAND_MACRO) {
- FunctionNode* fn = 0;
- Declaration declData(qdb_->primaryTreeRoot(), true);
- if (parseDeclaration(arg.first, declData)) {
- if (!declData.parentPath_.isEmpty()) {
+ QStringList parentPath;
+ FunctionNode *func = 0;
+
+ extra.root = qdb_->primaryTreeRoot();
+ extra.isMacro = true;
+ if (makeFunctionNode(arg.first, &parentPath, &func, extra)) {
+ if (!parentPath.isEmpty()) {
doc.startLocation().warning(tr("Invalid syntax in '\\%1'").arg(COMMAND_MACRO));
+ delete func;
+ func = 0;
}
- else if (declData.isFunction()) {
- fn = createFunctionNode(declData);
- fn->setMetaness(FunctionNode::MacroWithParams);
- QVector<Parameter> params = fn->parameters();
+ else {
+ func->setMetaness(FunctionNode::MacroWithParams);
+ QVector<Parameter> params = func->parameters();
for (int i = 0; i < params.size(); ++i) {
Parameter &param = params[i];
if (param.name().isEmpty() && !param.dataType().isEmpty()
&& param.dataType() != "...")
param = Parameter("", "", param.dataType());
}
- fn->setParameters(params);
+ func->setParameters(params);
}
- return fn;
+ return func;
}
else if (QRegExp("[A-Za-z_][A-Za-z0-9_]+").exactMatch(arg.first)) {
- fn = new FunctionNode(qdb_->primaryTreeRoot(), arg.first);
- fn->setAccess(Node::Public);
- fn->setLocation(doc.startLocation());
- fn->setMetaness(FunctionNode::MacroWithoutParams);
+ func = new FunctionNode(qdb_->primaryTreeRoot(), arg.first);
+ func->setAccess(Node::Public);
+ func->setLocation(doc.startLocation());
+ func->setMetaness(FunctionNode::MacroWithoutParams);
}
else {
doc.location().warning(tr("Invalid syntax in '\\%1'").arg(COMMAND_MACRO));
}
- return fn;
+ return func;
}
else if (nodeTypeMap.contains(command)) {
/*
@@ -572,17 +580,12 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc,
attached = true;
else
return 0; // never get here.
- FunctionNode* fn = 0;
- Declaration declData(qmlType, nodeType, attached);
- if (parseDeclaration(arg.first, declData)) {
- fn = createFunctionNode(declData);
- }
- else {
- Declaration declData(qmlType, nodeType, attached);
- if (parseDeclaration("void " + arg.first, declData)) {
- fn = createFunctionNode(declData);
- }
- }
+ FunctionNode* fn = makeFunctionNode(doc,
+ arg.first,
+ qmlType,
+ nodeType,
+ attached,
+ command);
if (fn) {
fn->setLocation(doc.startLocation());
if ((command == COMMAND_JSSIGNAL) ||
@@ -591,8 +594,6 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc,
(command == COMMAND_JSATTACHEDMETHOD))
fn->setGenus(Node::JS);
}
- else
- doc.location().warning(tr("Invalid syntax in '\\%1'").arg(command));
return fn;
}
}
@@ -1046,7 +1047,7 @@ void CppCodeParser::reset()
{
tokenizer = 0;
tok = 0;
- access_ = Node::Public;
+ access = Node::Public;
metaness_ = FunctionNode::Plain;
lastPath_.clear();
physicalModuleName.clear();
@@ -1384,308 +1385,276 @@ int CppCodeParser::matchFunctionModifier()
return -1;
}
-bool CppCodeParser::matchDeclaration(Declaration& declData)
+bool CppCodeParser::matchFunctionDecl(Aggregate *parent,
+ QStringList *parentPathPtr,
+ FunctionNode **funcPtr,
+ const QString &templateStuff,
+ ExtraFuncData& extra)
{
+ CodeChunk returnType;
+ QStringList parentPath;
+ QString name;
+
+ bool matched_QT_DEPRECATED = false;
+ bool matched_friend = false;
+ bool matched_static = false;
+ bool matched_inline = false;
+ bool matched_explicit = false;
+ bool matched_compat = false;
+
int token = tok;
while (token != -1) {
switch (token) {
case Tok_friend:
- declData.isFriend_ = true;
+ matched_friend = true;
break;
case Tok_inline:
- declData.isInline_ = true;
+ matched_inline = true;
break;
case Tok_explicit:
- declData.isExplicit_ = true;
+ matched_explicit = true;
break;
case Tok_static:
- declData.isStatic_ = true;
+ matched_static = true;
break;
case Tok_QT_DEPRECATED:
// no break here.
- declData.isQT_DEPRECATED_ = true;
+ matched_QT_DEPRECATED = true;
case Tok_QT_COMPAT:
- declData.isCompat_ = true;
+ matched_compat = true;
break;
}
token = matchFunctionModifier();
}
- declData.virtuality_ = FunctionNode::NonVirtual;
+ FunctionNode::Virtualness virtuality = FunctionNode::NonVirtual;
if (match(Tok_virtual)) {
- declData.virtuality_ = FunctionNode::NormalVirtual;
- if (!declData.isCompat_)
- declData.isCompat_ = matchCompat();
+ virtuality = FunctionNode::NormalVirtual;
+ if (!matched_compat)
+ matched_compat = matchCompat();
}
- if (!matchDataType(&declData.returnType_)) {
+ if (!matchDataType(&returnType)) {
if (tokenizer->parsingFnOrMacro()
&& (match(Tok_Q_DECLARE_FLAGS) ||
match(Tok_Q_PROPERTY) ||
match(Tok_Q_PRIVATE_PROPERTY)))
- declData.returnType_ = CodeChunk(previousLexeme());
- else
+ returnType = CodeChunk(previousLexeme());
+ else {
return false;
+ }
}
- if (!declData.isCompat_)
- declData.isCompat_ = matchCompat();
+ if (returnType.toString() == "QBool")
+ returnType = CodeChunk("bool");
+
+ if (!matched_compat)
+ matched_compat = matchCompat();
if (tok == Tok_operator &&
- (declData.returnType_.toString().isEmpty() ||
- declData.returnType_.toString().endsWith("::"))) {
+ (returnType.toString().isEmpty() ||
+ returnType.toString().endsWith("::"))) {
// 'QString::operator const char *()'
- declData.parentPath_ = declData.returnType_.toString().split(sep);
- declData.parentPath_.removeAll(QString());
- declData.returnType_ = CodeChunk();
+ parentPath = returnType.toString().split(sep);
+ parentPath.removeAll(QString());
+ returnType = CodeChunk();
readToken();
CodeChunk restOfName;
if (tok != Tok_Tilde && matchDataType(&restOfName)) {
- declData.name_ = "operator " + restOfName.toString();
+ name = "operator " + restOfName.toString();
}
else {
- declData.name_ = previousLexeme() + lexeme();
+ name = previousLexeme() + lexeme();
readToken();
while (tok != Tok_LeftParen && tok != Tok_Eoi) {
- declData.name_ += lexeme();
+ name += lexeme();
readToken();
}
}
- if (tok != Tok_LeftParen)
- return false; // This exit is never used.
+ if (tok != Tok_LeftParen) {
+ return false;
+ }
}
else if (tok == Tok_LeftParen) {
// constructor or destructor
- declData.parentPath_ = declData.returnType_.toString().split(sep);
- if (!declData.parentPath_.isEmpty()) {
- declData.name_ = declData.parentPath_.last();
- declData.parentPath_.erase(declData.parentPath_.end() - 1);
+ parentPath = returnType.toString().split(sep);
+ if (!parentPath.isEmpty()) {
+ name = parentPath.last();
+ parentPath.erase(parentPath.end() - 1);
}
- declData.returnType_ = CodeChunk();
+ returnType = CodeChunk();
}
else {
while (match(Tok_Ident)) {
- declData.name_ = previousLexeme();
+ name = previousLexeme();
/*
This is a hack to let QML module identifiers through.
*/
- matchModuleQualifier(declData.name_);
+ matchModuleQualifier(name);
matchTemplateAngles();
if (match(Tok_Gulbrandsen))
- declData.parentPath_.append(declData.name_);
+ parentPath.append(name);
else
break;
}
+
if (tok == Tok_operator) {
- declData.name_ = lexeme();
+ name = lexeme();
readToken();
while (tok != Tok_Eoi) {
- declData.name_ += lexeme();
+ name += lexeme();
readToken();
if (tok == Tok_LeftParen)
break;
}
}
- if (declData.parent_ && (tok == Tok_Semicolon ||
- tok == Tok_LeftBracket ||
- tok == Tok_Colon)
- && access_ == Node::Public) {
- matchVariableDecl(declData);
- return true;
- }
- if (tok != Tok_LeftParen) {
- return false; // mws says these failures should be investigated.
+ if (parent && (tok == Tok_Semicolon ||
+ tok == Tok_LeftBracket ||
+ tok == Tok_Colon)
+ && access != Node::Private) {
+ if (tok == Tok_LeftBracket) {
+ returnType.appendHotspot();
+
+ int bracketDepth0 = tokenizer->bracketDepth();
+ while ((tokenizer->bracketDepth() >= bracketDepth0 &&
+ tok != Tok_Eoi) ||
+ tok == Tok_RightBracket) {
+ returnType.append(lexeme());
+ readToken();
+ }
+ if (tok != Tok_Semicolon) {
+ return false;
+ }
+ }
+ else if (tok == Tok_Colon) {
+ returnType.appendHotspot();
+
+ while (tok != Tok_Semicolon && tok != Tok_Eoi) {
+ returnType.append(lexeme());
+ readToken();
+ }
+ if (tok != Tok_Semicolon) {
+ return false;
+ }
+ }
+
+ VariableNode *var = new VariableNode(parent, name);
+ var->setAccess(access);
+ var->setLocation(location());
+ var->setLeftType(returnType.left());
+ var->setRightType(returnType.right());
+ if (matched_compat)
+ var->setStatus(Node::Compat);
+ var->setStatic(matched_static);
+ return false;
}
+ if (tok != Tok_LeftParen)
+ return false;
}
readToken();
- declData.location_ = location();
- declData.access_ = access_;
- declData.metaness_ = metaness_;
// A left paren was seen. Parse the parameters
+ bool isQPrivateSignal = false;
+ QVector<Parameter> pvect;
if (tok != Tok_RightParen) {
do {
- if (!matchParameter(declData.pvect_, declData.isQPrivateSignal_))
- return false; // mws says these failures should be investigated.
+ if (!matchParameter(pvect, isQPrivateSignal))
+ return false;
} while (match(Tok_Comma));
}
// The parameters must end with a right paren
if (!match(Tok_RightParen))
- return false; // mws says these failures should be investigated.
-
- /*
- When the right paren is matched, it might be the end without a semicolon.
- e.g., if it is a macro. But there might be more for this declaration...
- */
+ return false;
// look for const
- declData.isConst_ = match(Tok_const);
-
- if (match(Tok_throw)) {
- if (match(Tok_LeftParen)) {
- while (tok != Tok_RightParen && tok != Tok_Eoi)
- readToken();
- if (tok != Tok_RightParen)
- return false;
- else
- readToken();
- }
- }
- else
- match(Tok_noexcept);
+ bool matchedConst = match(Tok_const);
- // look for "= 0" indicating pure virtual
+ // look for 0 indicating pure virtual
if (match(Tok_Equal) && match(Tok_Number))
- declData.virtuality_ = FunctionNode::PureVirtual;
+ virtuality = FunctionNode::PureVirtual;
- // look for ":" indicating ctors which must be skipped
+ // look for colon indicating ctors which must be skipped
if (match(Tok_Colon)) {
while (tok != Tok_LeftBrace && tok != Tok_Eoi)
readToken();
}
// If no ';' expect a body, which must be skipped.
+ bool body_expected = false;
+ bool body_present = false;
if (!match(Tok_Semicolon) && tok != Tok_Eoi) {
- declData.bodyExpected_ = true;
+ body_expected = true;
int nesting = tokenizer->braceDepth();
- if (!match(Tok_LeftBrace)) {
- // It is correct for macro calls to return here.
- return false; // mws says these failures should be investigated
- }
+ if (!match(Tok_LeftBrace))
+ return false;
// skip the body
while (tokenizer->braceDepth() >= nesting && tok != Tok_Eoi)
readToken();
- declData.bodyPresent_ = true;
+ body_present = true;
match(Tok_RightBrace);
}
+
+ FunctionNode *func = 0;
+ bool createFunctionNode = false;
if (parsingHeaderFile_) {
- if (declData.isFriend_) {
- if (declData.isInline_) {
+ if (matched_friend) {
+ if (matched_inline) {
// nothing yet
}
- if (declData.bodyPresent_) {
- if (declData.bodyExpected_) {
+ if (body_present) {
+ if (body_expected) {
// nothing yet
}
- if (declData.parent_ && declData.parent_->parent())
- declData.parent_ = declData.parent_->parent();
+ createFunctionNode = true;
+ if (parent && parent->parent())
+ parent = parent->parent();
else
- return false; // This exit is never used.
+ return false;
}
}
+ else
+ createFunctionNode = true;
}
- declData.result_ = Function;
- return true;
-}
-
-/*!
- This function creates a variable node from the data in \a declData.
- This should be the only place where a variable node is created.
- */
-VariableNode* CppCodeParser::createVariableNode(Declaration& declData)
-{
- /*
- Don't create a variable node if the access mode
- is not public.
- */
- VariableNode* var = 0;
- if (declData.access_ == Node::Public) {
- var = new VariableNode(declData.parent_, declData.name_);
- var->setAccess(declData.access_);
- var->setLocation(location());
- var->setLeftType(declData.returnType_.left());
- var->setRightType(declData.returnType_.right());
- if (declData.isCompat_)
- var->setStatus(Node::Compat);
- var->setStatic(declData.isStatic_);
- }
- return var;
-}
-
-/*!
- This function creates a function node from the data in \a declData.
- This should be the only place where a function node is created.
- */
-FunctionNode* CppCodeParser::createFunctionNode(Declaration& declData)
-{
- FunctionNode* fn = new FunctionNode(declData.type_, declData.parent_, declData.name_, declData.isAttached_);
- if (declData.isFriend_)
- declData.access_ = Node::Public;
- fn->setAccess(declData.access_);
- fn->setLocation(declData.location_);
- fn->setReturnType(declData.returnType_.toString());
- fn->setParentPath(declData.parentPath_);
- fn->setTemplateStuff(declData.templateStuff_);
- if (declData.isCompat_)
- fn->setStatus(Node::Compat);
- if (declData.isQT_DEPRECATED_)
- fn->setStatus(Node::Deprecated);
- if (declData.isExplicit_) { /* What can be done? */ }
- fn->setMetaness(declData.metaness_);
- if (declData.parent_) {
- if (declData.name_ == declData.parent_->name())
- fn->setMetaness(FunctionNode::Ctor);
- else if (declData.name_.startsWith(QLatin1Char('~')))
- fn->setMetaness(FunctionNode::Dtor);
- }
- fn->setStatic(declData.isStatic_);
- fn->setConst(declData.isConst_);
- fn->setVirtualness(declData.virtuality_);
- if (declData.isQPrivateSignal_)
- fn->setPrivateSignal();
- if (!declData.pvect_.isEmpty()) {
- fn->setParameters(declData.pvect_);
- }
- return fn;
-}
-
-/*!
- Variable declarations get parsed by the same function that
- parses function declarations, because variable declarations
- look like function declarations until the end. As input, it
- gets access to the data saved from parsing what it thought
- was a function declaration in \a declData.
- */
-void CppCodeParser::matchVariableDecl(Declaration& declData)
-{
- if (tok == Tok_LeftBracket) {
- declData.returnType_.appendHotspot();
-
- int bracketDepth0 = tokenizer->bracketDepth();
- while ((tokenizer->bracketDepth() >= bracketDepth0 &&
- tok != Tok_Eoi) ||
- tok == Tok_RightBracket) {
- declData.returnType_.append(lexeme());
- readToken();
- }
- }
- else if (tok == Tok_Colon) {
- declData.returnType_.appendHotspot();
-
- while (tok != Tok_Semicolon && tok != Tok_Eoi) {
- declData.returnType_.append(lexeme());
- readToken();
- }
- }
- if (match(Tok_Equal)) {
- int nesting = tokenizer->braceDepth();
- if (match(Tok_LeftBrace)) {
- // skip the body
- while (tokenizer->braceDepth() >= nesting && tok != Tok_Eoi)
- readToken();
- }
- while (tok != Tok_Semicolon && tok != Tok_Eoi) {
- readToken();
- }
- }
- declData.access_ = access_;
-
- if (tok == Tok_Semicolon)
- declData.result_ = Variable;
else
- declData.result_ = Ignore;
+ createFunctionNode = true;
+
+ if (createFunctionNode) {
+ func = new FunctionNode(extra.type, parent, name, extra.isAttached);
+ if (matched_friend)
+ access = Node::Public;
+ func->setAccess(access);
+ func->setLocation(location());
+ func->setReturnType(returnType.toString());
+ func->setParentPath(parentPath);
+ func->setTemplateStuff(templateStuff);
+ if (matched_compat)
+ func->setStatus(Node::Compat);
+ if (matched_QT_DEPRECATED)
+ func->setStatus(Node::Deprecated);
+ if (matched_explicit) { /* What can be done? */ }
+ func->setMetaness(metaness_);
+ if (parent) {
+ if (name == parent->name())
+ func->setMetaness(FunctionNode::Ctor);
+ else if (name.startsWith(QLatin1Char('~')))
+ func->setMetaness(FunctionNode::Dtor);
+ }
+ func->setStatic(matched_static);
+ func->setConst(matchedConst);
+ func->setVirtualness(virtuality);
+ if (isQPrivateSignal)
+ func->setPrivateSignal();
+ if (!pvect.isEmpty()) {
+ func->setParameters(pvect);
+ }
+ }
+ if (parentPathPtr != 0)
+ *parentPathPtr = parentPath;
+ if (funcPtr != 0)
+ *funcPtr = func;
+ return true;
}
bool CppCodeParser::matchBaseSpecifier(ClassNode *classe, bool isClass)
@@ -1771,7 +1740,7 @@ bool CppCodeParser::matchClassDecl(Aggregate *parent,
This is enough to recognize a class definition.
*/
ClassNode *classe = new ClassNode(parent, previousLexeme());
- classe->setAccess(access_);
+ classe->setAccess(access);
classe->setLocation(location());
if (compat)
classe->setStatus(Node::Compat);
@@ -1784,14 +1753,14 @@ bool CppCodeParser::matchClassDecl(Aggregate *parent,
if (!match(Tok_LeftBrace))
return false;
- Node::Access outerAccess = access_;
- access_ = isClass ? Node::Private : Node::Public;
+ Node::Access outerAccess = access;
+ access = isClass ? Node::Private : Node::Public;
FunctionNode::Metaness outerMetaness = metaness_;
metaness_ = FunctionNode::Plain;
bool matches = (matchDeclList(classe) && match(Tok_RightBrace) &&
match(Tok_Semicolon));
- access_ = outerAccess;
+ access = outerAccess;
metaness_ = outerMetaness;
return matches;
}
@@ -1815,7 +1784,7 @@ bool CppCodeParser::matchNamespaceDecl(Aggregate *parent)
ns = static_cast<NamespaceNode*>(parent->findChildNode(namespaceName, Node::Namespace));
if (!ns) {
ns = new NamespaceNode(parent, namespaceName);
- ns->setAccess(access_);
+ ns->setAccess(access);
ns->setLocation(location());
}
@@ -1897,7 +1866,7 @@ bool CppCodeParser::matchUsingDecl(Aggregate* parent)
return true;
}
-bool CppCodeParser::matchEnumItem(Aggregate *parent, EnumNode* en)
+bool CppCodeParser::matchEnumItem(Aggregate *parent, EnumNode *enume)
{
if (!match(Tok_Ident))
return false;
@@ -1921,14 +1890,14 @@ bool CppCodeParser::matchEnumItem(Aggregate *parent, EnumNode* en)
}
}
- if (en) {
+ if (enume) {
QString strVal = val.toString();
if (strVal.isEmpty()) {
- if (en->items().isEmpty()) {
+ if (enume->items().isEmpty()) {
strVal = "0";
}
else {
- QString last = en->items().last().value();
+ QString last = enume->items().last().value();
bool ok;
int n = last.toInt(&ok);
if (ok) {
@@ -1944,11 +1913,11 @@ bool CppCodeParser::matchEnumItem(Aggregate *parent, EnumNode* en)
}
}
- en->addItem(EnumItem(name, strVal));
+ enume->addItem(EnumItem(name, strVal));
}
else {
VariableNode *var = new VariableNode(parent, name);
- var->setAccess(access_);
+ var->setAccess(access);
var->setLocation(location());
var->setLeftType("const int");
var->setStatic(true);
@@ -1967,21 +1936,21 @@ bool CppCodeParser::matchEnumDecl(Aggregate *parent)
if (tok != Tok_LeftBrace)
return false;
- EnumNode* en = 0;
+ EnumNode *enume = 0;
if (!name.isEmpty()) {
- en = new EnumNode(parent, name);
- en->setAccess(access_);
- en->setLocation(location());
+ enume = new EnumNode(parent, name);
+ enume->setAccess(access);
+ enume->setLocation(location());
}
readToken();
- if (!matchEnumItem(parent, en))
+ if (!matchEnumItem(parent, enume))
return false;
while (match(Tok_Comma)) {
- if (!matchEnumItem(parent, en))
+ if (!matchEnumItem(parent, enume))
return false;
}
return match(Tok_RightBrace) && match(Tok_Semicolon);
@@ -2001,7 +1970,7 @@ bool CppCodeParser::matchTypedefDecl(Aggregate *parent)
if (parent && !parent->findChildNode(name, Node::Typedef)) {
TypedefNode* td = new TypedefNode(parent, name);
- td->setAccess(access_);
+ td->setAccess(access);
td->setLocation(location());
}
return true;
@@ -2122,6 +2091,7 @@ bool CppCodeParser::matchProperty(Aggregate *parent)
*/
bool CppCodeParser::matchDeclList(Aggregate *parent)
{
+ ExtraFuncData extra;
QString templateStuff;
int braceDepth0 = tokenizer->braceDepth();
if (tok == Tok_RightBrace) // prevents failure on empty body
@@ -2159,23 +2129,23 @@ bool CppCodeParser::matchDeclList(Aggregate *parent)
break;
case Tok_private:
readToken();
- access_ = Node::Private;
+ access = Node::Private;
metaness_ = FunctionNode::Plain;
break;
case Tok_protected:
readToken();
- access_ = Node::Protected;
+ access = Node::Protected;
metaness_ = FunctionNode::Plain;
break;
case Tok_public:
readToken();
- access_ = Node::Public;
+ access = Node::Public;
metaness_ = FunctionNode::Plain;
break;
case Tok_signals:
case Tok_Q_SIGNALS:
readToken();
- access_ = Node::Public;
+ access = Node::Public;
metaness_ = FunctionNode::Signal;
break;
case Tok_slots:
@@ -2227,7 +2197,7 @@ bool CppCodeParser::matchDeclList(Aggregate *parent)
if (match(Tok_Comma) && match(Tok_Ident)) {
QString name = previousLexeme();
TypedefNode *flagsNode = new TypedefNode(parent, flagsType);
- flagsNode->setAccess(access_);
+ flagsNode->setAccess(access);
flagsNode->setLocation(location());
EnumNode* en = static_cast<EnumNode*>(parent->findChildNode(name, Node::Enum));
if (en)
@@ -2245,19 +2215,7 @@ bool CppCodeParser::matchDeclList(Aggregate *parent)
match(Tok_RightParen);
break;
default:
- Declaration declData(parent, templateStuff);
- if (matchDeclaration(declData)) {
- if (declData.isFunction() && !declData.ignoreThisDecl())
- (void) createFunctionNode(declData);
- else if (declData.isVariable()) {
- /*
- Always create the variable node because
- we are parsing a .h file
- */
- (void) createVariableNode(declData);
- }
- }
- else {
+ if (!matchFunctionDecl(parent, 0, 0, templateStuff, extra)) {
while (tok != Tok_Eoi &&
(tokenizer->braceDepth() > braceDepth0 ||
(!match(Tok_Semicolon) &&
@@ -2278,6 +2236,7 @@ bool CppCodeParser::matchDeclList(Aggregate *parent)
*/
bool CppCodeParser::matchDocsAndStuff()
{
+ ExtraFuncData extra;
const QSet<QString>& topicCommandsAllowed = topicCommands();
const QSet<QString>& otherMetacommandsAllowed = otherMetaCommands();
const QSet<QString>& metacommandsAllowed = topicCommandsAllowed + otherMetacommandsAllowed;
@@ -2305,30 +2264,27 @@ bool CppCodeParser::matchDocsAndStuff()
const TopicList& topics = doc.topicsUsed();
if (!topics.isEmpty()) {
topic = topics[0].topic;
- if (topic.startsWith("qml")) {
- if ((topic == COMMAND_QMLPROPERTY) ||
- (topic == COMMAND_QMLPROPERTYGROUP) ||
- (topic == COMMAND_QMLATTACHEDPROPERTY)) {
- isQmlPropertyTopic = true;
- }
+ if ((topic == COMMAND_QMLPROPERTY) ||
+ (topic == COMMAND_QMLPROPERTYGROUP) ||
+ (topic == COMMAND_QMLATTACHEDPROPERTY)) {
+ isQmlPropertyTopic = true;
}
- else if (topic.startsWith("js")) {
- if ((topic == COMMAND_JSPROPERTY) ||
- (topic == COMMAND_JSPROPERTYGROUP) ||
- (topic == COMMAND_JSATTACHEDPROPERTY)) {
- isJsPropertyTopic = true;
- }
+ else if ((topic == COMMAND_JSPROPERTY) ||
+ (topic == COMMAND_JSPROPERTYGROUP) ||
+ (topic == COMMAND_JSATTACHEDPROPERTY)) {
+ isJsPropertyTopic = true;
}
}
NodeList nodes;
DocList docs;
if (topic.isEmpty()) {
+ QStringList parentPath;
+ FunctionNode *clone;
FunctionNode *func = 0;
- Declaration declData(qdb_->primaryTreeRoot());
- matchDeclaration(declData);
- if (declData.isFunction()) {
- func = qdb_->findFunctionNode(declData.parentPath_, declData);
+
+ if (matchFunctionDecl(0, &parentPath, &clone, QString(), extra)) {
+ func = qdb_->findFunctionNode(parentPath, clone);
/*
If the node was not found, then search for it in the
open C++ namespaces. We don't expect this search to
@@ -2336,13 +2292,14 @@ bool CppCodeParser::matchDocsAndStuff()
very often.
*/
if (func == 0)
- func = qdb_->findNodeInOpenNamespace(declData.parentPath_, declData);
+ func = qdb_->findNodeInOpenNamespace(parentPath, clone);
if (func) {
- func->borrowParameterNames(declData);
+ func->borrowParameterNames(clone);
nodes.append(func);
docs.append(doc);
}
+ delete clone;
}
else {
doc.location().warning(tr("Cannot tie this documentation to anything"),
@@ -2413,9 +2370,11 @@ bool CppCodeParser::matchDocsAndStuff()
matchUsingDecl(0);
}
else {
- Declaration declData(qdb_->primaryTreeRoot());
- matchDeclaration(declData);
- if (declData.isFunction()) {
+ QStringList parentPath;
+ FunctionNode *clone;
+ FunctionNode *node = 0;
+
+ if (matchFunctionDecl(0, &parentPath, &clone, QString(), extra)) {
/*
The location of the definition is more interesting
than that of the declaration. People equipped with
@@ -2425,9 +2384,10 @@ bool CppCodeParser::matchDocsAndStuff()
Signals are implemented in uninteresting files
generated by moc.
*/
- FunctionNode* node = qdb_->findFunctionNode(declData.parentPath_, declData);
- if (node && node->metaness() != FunctionNode::Signal)
- node->setLocation(declData.location_);
+ node = qdb_->findFunctionNode(parentPath, clone);
+ if (node != 0 && node->metaness() != FunctionNode::Signal)
+ node->setLocation(clone->location());
+ delete clone;
}
else {
if (tok != Tok_Doc)
@@ -2444,7 +2404,10 @@ bool CppCodeParser::matchDocsAndStuff()
If a match is found, \a funcPtr is set to point to the matching node
and true is returned.
*/
-bool CppCodeParser::parseDeclaration(const QString& signature, Declaration& declData)
+bool CppCodeParser::makeFunctionNode(const QString& signature,
+ QStringList* parentPathPtr,
+ FunctionNode** funcPtr,
+ ExtraFuncData& extra)
{
Tokenizer* outerTokenizer = tokenizer;
int outerTok = tok;
@@ -2455,9 +2418,11 @@ bool CppCodeParser::parseDeclaration(const QString& signature, Declaration& decl
tokenizer = &stringTokenizer;
readToken();
- inMacroCommand_ = declData.isMacro_;
- bool ok = matchDeclaration(declData);
+ inMacroCommand_ = extra.isMacro;
+ bool ok = matchFunctionDecl(extra.root, parentPathPtr, funcPtr, QString(), extra);
inMacroCommand_ = false;
+ // potential memory leak with funcPtr
+
tokenizer = outerTokenizer;
tok = outerTok;
return ok;
@@ -2491,6 +2456,34 @@ bool CppCodeParser::parseParameters(const QString& parameters,
return true;
}
+/*!
+ Create a new FunctionNode for a QML method or signal, as
+ specified by \a type, as a child of \a parent. \a sig is
+ the complete signature, and if \a attached is true, the
+ method or signal is "attached". \a qdoctag is the text of
+ the \a type.
+
+ \a parent is the QML class node. The QML module and QML
+ type names have already been consumed to find \a parent.
+ What remains in \a sig is the method signature. The method
+ must be a child of \a parent.
+ */
+FunctionNode* CppCodeParser::makeFunctionNode(const Doc& doc,
+ const QString& sig,
+ Aggregate* parent,
+ Node::NodeType type,
+ bool attached,
+ QString qdoctag)
+{
+ QStringList pp;
+ FunctionNode* fn = 0;
+ ExtraFuncData extra(parent, type, attached);
+ if (!makeFunctionNode(sig, &pp, &fn, extra) && !makeFunctionNode("void " + sig, &pp, &fn, extra)) {
+ doc.location().warning(tr("Invalid syntax in '\\%1'").arg(qdoctag));
+ }
+ return fn;
+}
+
void CppCodeParser::parseQiteratorDotH(const Location &location, const QString &filePath)
{
QFile file(filePath);
diff --git a/src/qdoc/cppcodeparser.h b/src/qdoc/cppcodeparser.h
index cc0b0f2fe..ec0448232 100644
--- a/src/qdoc/cppcodeparser.h
+++ b/src/qdoc/cppcodeparser.h
@@ -51,6 +51,16 @@ class CppCodeParser : public CodeParser
{
Q_DECLARE_TR_FUNCTIONS(QDoc::CppCodeParser)
+ struct ExtraFuncData {
+ Aggregate* root; // Used as the parent.
+ Node::NodeType type; // The node type: Function, etc.
+ bool isAttached; // If true, the method is attached.
+ bool isMacro; // If true, we are parsing a macro signature.
+ ExtraFuncData() : root(0), type(Node::Function), isAttached(false), isMacro(false) { }
+ ExtraFuncData(Aggregate* r, Node::NodeType t, bool a)
+ : root(r), type(t), isAttached(a), isMacro(false) { }
+ };
+
public:
CppCodeParser();
~CppCodeParser();
@@ -109,7 +119,11 @@ protected:
bool matchTemplateHeader();
bool matchDataType(CodeChunk *type, QString *var = 0);
bool matchParameter(QVector<Parameter>& pvect, bool& isQPrivateSignal);
- bool matchDeclaration(Declaration& declData);
+ bool matchFunctionDecl(Aggregate *parent,
+ QStringList *parentPathPtr,
+ FunctionNode **funcPtr,
+ const QString &templateStuff,
+ ExtraFuncData& extra);
bool matchBaseSpecifier(ClassNode *classe, bool isClass);
bool matchBaseList(ClassNode *classe, bool isClass);
bool matchClassDecl(Aggregate *parent,
@@ -122,22 +136,28 @@ protected:
bool matchProperty(Aggregate *parent);
bool matchDeclList(Aggregate *parent);
bool matchDocsAndStuff();
- bool parseDeclaration(const QString &synopsis, Declaration& declData);
+ bool makeFunctionNode(const QString &synopsis,
+ QStringList *parentPathPtr,
+ FunctionNode **funcPtr,
+ ExtraFuncData& params);
+ FunctionNode* makeFunctionNode(const Doc& doc,
+ const QString& sig,
+ Aggregate* parent,
+ Node::NodeType type,
+ bool attached,
+ QString qdoctag);
void parseQiteratorDotH(const Location &location, const QString &filePath);
void instantiateIteratorMacro(const QString &container,
const QString &includeFile,
const QString &macroDef);
void createExampleFileNodes(DocumentNode *dn);
- FunctionNode* createFunctionNode(Declaration& declData);
- VariableNode* createVariableNode(Declaration& declData);
int matchFunctionModifier();
- void matchVariableDecl(Declaration& declData);
protected:
QMap<QString, Node::NodeType> nodeTypeMap;
Tokenizer *tokenizer;
int tok;
- Node::Access access_;
+ Node::Access access;
FunctionNode::Metaness metaness_;
QString physicalModuleName;
QStringList lastPath_;
diff --git a/src/qdoc/generator.cpp b/src/qdoc/generator.cpp
index b4c2b513a..81ad2a94b 100644
--- a/src/qdoc/generator.cpp
+++ b/src/qdoc/generator.cpp
@@ -753,7 +753,7 @@ 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->plainSignature()));
+ node->location().warning(tr("No documentation for '%1'").arg(node->plainFullName()));
}
}
else {
diff --git a/src/qdoc/main.cpp b/src/qdoc/main.cpp
index 4c4354773..8ebebda79 100644
--- a/src/qdoc/main.cpp
+++ b/src/qdoc/main.cpp
@@ -788,13 +788,13 @@ int main(int argc, char **argv)
translators.clear();
#endif
QmlTypeNode::terminate();
- //#define DEBUG_SHUTDOWN_CRASH
+
#ifdef DEBUG_SHUTDOWN_CRASH
- Generator::startDebugging("main(): Delete qdoc database");
+ qDebug() << "main(): Delete qdoc database";
#endif
QDocDatabase::destroyQdocDB();
#ifdef DEBUG_SHUTDOWN_CRASH
- Generator::stopDebugging("main(): qdoc database deleted");
+ qDebug() << "main(): qdoc database deleted";
#endif
return EXIT_SUCCESS;
diff --git a/src/qdoc/node.cpp b/src/qdoc/node.cpp
index de8c2815f..9740f984f 100644
--- a/src/qdoc/node.cpp
+++ b/src/qdoc/node.cpp
@@ -165,29 +165,6 @@ 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
@@ -861,7 +838,7 @@ Node* Aggregate::findChildNode(const QString& name, NodeType type)
}
/*!
- Find a function node that is a child of this node, such
+ Find a function node that is a child of this nose, such
that the function node has the specified \a name.
*/
FunctionNode *Aggregate::findFunctionNode(const QString& name, const QString& params) const
@@ -930,58 +907,21 @@ FunctionNode *Aggregate::findFunctionNode(const QString& name, const QString& pa
/*!
Find the function node that is a child of this node, such
that the function has the same name and signature as the
- function described in \a f1.
+ \a clone node.
*/
-FunctionNode *Aggregate::findFunctionNode(const Declaration& f1) const
+FunctionNode *Aggregate::findFunctionNode(const FunctionNode *clone) const
{
- QMap<QString,Node*>::ConstIterator c = primaryFunctionMap_.constFind(f1.name_);
+ QMap<QString,Node*>::ConstIterator c = primaryFunctionMap_.constFind(clone->name());
if (c != primaryFunctionMap_.constEnd()) {
- FunctionNode* f2 = (FunctionNode*) *c;
- if (f1.isConst_ == f2->isConst()) {
- if (isSameSignature(f1.pvect_, f2)) {
- return f2;
- }
+ if (isSameSignature(clone, (FunctionNode *) *c)) {
+ return (FunctionNode *) *c;
}
- if (secondaryFunctionMap_.contains(f1.name_)) {
- const NodeList& secs = secondaryFunctionMap_[f1.name_];
+ else if (secondaryFunctionMap_.contains(clone->name())) {
+ const NodeList& secs = secondaryFunctionMap_[clone->name()];
NodeList::ConstIterator s = secs.constBegin();
while (s != secs.constEnd()) {
- f2 = (FunctionNode*) *s;
- if (f1.isConst_ == f2->isConst()) {
- if (isSameSignature(f1.pvect_, f2))
- return f2;
- }
- ++s;
- }
- }
- }
- return 0;
-}
-
-/*!
- Find the function node that is a child of this node, such
- that the function has the same name and signature as the
- function node \a f1.
- */
-FunctionNode *Aggregate::findFunctionNode(const FunctionNode* f1) const
-{
- QMap<QString,Node*>::ConstIterator c = primaryFunctionMap_.constFind(f1->name());
- if (c != primaryFunctionMap_.constEnd()) {
- FunctionNode* f2 = (FunctionNode*) *c;
- if (f1->isConst() == f2->isConst()) {
- if (isSameSignature(f1->parameters(), f2)) {
- return f2;
- }
- }
- if (secondaryFunctionMap_.contains(f1->name())) {
- const NodeList& secs = secondaryFunctionMap_[f1->name()];
- NodeList::ConstIterator s = secs.constBegin();
- while (s != secs.constEnd()) {
- f2 = (FunctionNode*) *s;
- if (f1->isConst() == f2->isConst()) {
- if (isSameSignature(f1->parameters(), f2))
- return f2;
- }
+ if (isSameSignature(clone, (FunctionNode *) *s))
+ return (FunctionNode *) *s;
++s;
}
}
@@ -1225,19 +1165,18 @@ void Aggregate::setIncludes(const QStringList& includes)
}
/*!
- Compare the function signature contained parameter vector
- \a pv1 with the signature of the function node \a f2, and
- return \c true if they are the same.
+ f1 is always the clone
*/
-bool Aggregate::isSameSignature(const QVector<Parameter>& pv1, const FunctionNode* f2)
+bool Aggregate::isSameSignature(const FunctionNode *f1, const FunctionNode *f2)
{
- const QVector<Parameter>& pv2 = f2->parameters();
- if (pv1.size() != pv2.size())
+ if (f1->parameters().size() != f2->parameters().size())
+ return false;
+ if (f1->isConst() != f2->isConst())
return false;
- QVector<Parameter>::ConstIterator p1 = pv1.constBegin();
- QVector<Parameter>::ConstIterator p2 = pv2.constBegin();
- while (p2 != pv2.constEnd()) {
+ QVector<Parameter>::ConstIterator p1 = f1->parameters().constBegin();
+ QVector<Parameter>::ConstIterator p2 = f2->parameters().constBegin();
+ while (p2 != f2->parameters().constEnd()) {
if ((*p1).hasType() && (*p2).hasType()) {
if ((*p1).rightType() != (*p2).rightType())
return false;
@@ -2090,11 +2029,11 @@ void FunctionNode::addParameter(const Parameter& parameter)
/*!
*/
-void FunctionNode::borrowParameterNames(const Declaration& declData)
+void FunctionNode::borrowParameterNames(const FunctionNode *source)
{
QVector<Parameter>::Iterator t = parameters_.begin();
- QVector<Parameter>::ConstIterator s = declData.pvect_.constBegin();
- while (s != declData.pvect_.constEnd() && t != parameters_.end()) {
+ QVector<Parameter>::ConstIterator s = source->parameters_.constBegin();
+ while (s != source->parameters_.constEnd() && t != parameters_.end()) {
if (!(*s).name().isEmpty())
(*t).setName((*s).name());
++s;
@@ -2194,10 +2133,10 @@ QStringList FunctionNode::reconstructParameters(bool values) const
is true, the default values of the parameters are included, if
present.
*/
-QString FunctionNode::signature(bool values, bool noReturnType) const
+QString FunctionNode::signature(bool values) const
{
QString s;
- if (!noReturnType && !returnType().isEmpty())
+ if (!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 cc2c784fa..945bc2187 100644
--- a/src/qdoc/node.h
+++ b/src/qdoc/node.h
@@ -53,7 +53,6 @@ class ExampleNode;
class TypedefNode;
class QmlTypeNode;
class QDocDatabase;
-class Declaration;
class FunctionNode;
class PropertyNode;
class CollectionNode;
@@ -160,9 +159,7 @@ 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(); }
@@ -373,37 +370,6 @@ private:
};
Q_DECLARE_TYPEINFO(Node::DocSubtype, Q_PRIMITIVE_TYPE);
-class Parameter
-{
-public:
- Parameter() {}
- Parameter(const QString& dataType,
- const QString& rightType = QString(),
- const QString& name = QString(),
- const QString& defaultValue = QString());
- Parameter(const Parameter& p);
-
- Parameter& operator=(const Parameter& p);
-
- void setName(const QString& name) { name_ = name; }
-
- bool hasType() const { return dataType_.length() + rightType_.length() > 0; }
- const QString& dataType() const { return dataType_; }
- const QString& rightType() const { return rightType_; }
- const QString& name() const { return name_; }
- const QString& defaultValue() const { return defaultValue_; }
-
- QString reconstruct(bool value = false) const;
-
- public:
- QString dataType_;
- QString rightType_; // mws says remove this 04/08/2015
- QString name_;
- QString defaultValue_;
-};
-//friend class QTypeInfo<Parameter>;
-//Q_DECLARE_TYPEINFO(Parameter, Q_MOVABLE_TYPE);
-
class Aggregate : public Node
{
public:
@@ -413,8 +379,7 @@ public:
Node* findChildNode(const QString& name, NodeType type);
virtual void findChildren(const QString& name, NodeList& nodes) const Q_DECL_OVERRIDE;
FunctionNode* findFunctionNode(const QString& name, const QString& params) const;
- FunctionNode* findFunctionNode(const Declaration& declData) const;
- FunctionNode* findFunctionNode(const FunctionNode* f1) const;
+ FunctionNode* findFunctionNode(const FunctionNode* clone) const;
void addInclude(const QString &include);
void setIncludes(const QStringList &includes);
void normalizeOverloads();
@@ -456,7 +421,7 @@ protected:
private:
friend class Node;
- static bool isSameSignature(const QVector<Parameter>& pv1, const FunctionNode* f2);
+ static bool isSameSignature(const FunctionNode* f1, const FunctionNode* f2);
void removeRelated(Node* pseudoChild);
void addRelated(Node* pseudoChild);
@@ -853,6 +818,38 @@ inline void EnumNode::setFlagsType(TypedefNode* t)
t->setAssociatedEnum(this);
}
+class Parameter
+{
+public:
+ Parameter() {}
+ Parameter(const QString& dataType,
+ const QString& rightType = QString(),
+ const QString& name = QString(),
+ const QString& defaultValue = QString());
+ Parameter(const Parameter& p);
+
+ Parameter& operator=(const Parameter& p);
+
+ void setName(const QString& name) { name_ = name; }
+
+ bool hasType() const { return dataType_.length() + rightType_.length() > 0; }
+ const QString& dataType() const { return dataType_; }
+ const QString& rightType() const { return rightType_; }
+ const QString& name() const { return name_; }
+ const QString& defaultValue() const { return defaultValue_; }
+
+ QString reconstruct(bool value = false) const;
+
+ public:
+ QString dataType_;
+ QString rightType_; // mws says remove this 04/08/2015
+ QString name_;
+ QString defaultValue_;
+};
+
+//friend class QTypeInfo<Parameter>;
+//Q_DECLARE_TYPEINFO(Parameter, Q_MOVABLE_TYPE);
+
class FunctionNode : public LeafNode
{
public:
@@ -883,7 +880,7 @@ public:
void setReimplemented(bool b);
void addParameter(const Parameter& parameter);
inline void setParameters(const QVector<Parameter>& parameters);
- void borrowParameterNames(const Declaration& declData);
+ void borrowParameterNames(const FunctionNode* source);
void setReimplementedFrom(FunctionNode* from);
const QString& returnType() const { return returnType_; }
@@ -929,7 +926,7 @@ public:
bool hasActiveAssociatedProperty() const;
QStringList reconstructParameters(bool values = false) const;
- virtual QString signature(bool values, bool noReturnType = false) const;
+ QString signature(bool values = 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(); }
@@ -971,97 +968,6 @@ private:
QList<FunctionNode*> reimplementedBy_;
};
-enum ParseResult { Ignore, SyntaxError, Function, Variable };
-
-class Declaration
-{
- public:
- Declaration()
- : result_(Ignore), parent_(0), type_(Node::Function), access_(Node::Public),
- metaness_(FunctionNode::Plain), bodyExpected_(false), bodyPresent_(false),
- isAttached_(false), isMacro_(false), isQPrivateSignal_(false), isQT_DEPRECATED_(false),
- isFriend_(false), isStatic_(false), isInline_(false), isExplicit_(false), isCompat_(false),
- isConst_(false), virtuality_(FunctionNode::NonVirtual) { }
-
- Declaration(Aggregate* p)
- : result_(Ignore), parent_(p), type_(Node::Function), access_(Node::Public),
- metaness_(FunctionNode::Plain), bodyExpected_(false), bodyPresent_(false),
- isAttached_(false), isMacro_(false), isQPrivateSignal_(false), isQT_DEPRECATED_(false),
- isFriend_(false), isStatic_(false), isInline_(false), isExplicit_(false), isCompat_(false),
- isConst_(false), virtuality_(FunctionNode::NonVirtual) { }
-
- Declaration(Aggregate* p, Node::NodeType t, bool isAttached)
- : result_(Ignore), parent_(p), type_(t), access_(Node::Public),
- metaness_(FunctionNode::Plain), bodyExpected_(false), bodyPresent_(false),
- isAttached_(isAttached), isMacro_(false), isQPrivateSignal_(false), isQT_DEPRECATED_(false),
- isFriend_(false), isStatic_(false), isInline_(false), isExplicit_(false), isCompat_(false),
- isConst_(false), virtuality_(FunctionNode::NonVirtual) { }
-
- Declaration(Aggregate* p, const QString& t)
- : result_(Ignore), parent_(p), templateStuff_(t), type_(Node::Function), access_(Node::Public),
- metaness_(FunctionNode::Plain), bodyExpected_(false), bodyPresent_(false),
- isAttached_(false), isMacro_(false), isQPrivateSignal_(false), isQT_DEPRECATED_(false),
- isFriend_(false), isStatic_(false), isInline_(false), isExplicit_(false), isCompat_(false),
- isConst_(false), virtuality_(FunctionNode::NonVirtual) { }
-
- Declaration(Aggregate* p, bool isMacro)
- : result_(Ignore), parent_(p), type_(Node::Function), access_(Node::Public),
- metaness_(FunctionNode::Plain), bodyExpected_(false), bodyPresent_(false),
- isAttached_(false), isMacro_(isMacro), isQPrivateSignal_(false), isQT_DEPRECATED_(false),
- isFriend_(false), isStatic_(false), isInline_(false), isExplicit_(false), isCompat_(false),
- isConst_(false), virtuality_(FunctionNode::NonVirtual) { }
-
- void clear() {
- parent_ = 0;
- type_ = Node::Function;
- access_ = Node::Public;
- metaness_ = FunctionNode::Plain;
- bodyExpected_ = false;
- bodyPresent_ = false;
- isAttached_ = false;
- isMacro_ = false;
- isQPrivateSignal_ = false;
- isQT_DEPRECATED_ = false;
- isFriend_ = false;
- isStatic_ = false;
- isInline_ = false;
- isExplicit_ = false;
- isCompat_ = false;
- isConst_ = false;
- virtuality_ = FunctionNode::NonVirtual;
- }
-
- bool ignoreThisDecl() const { return (isFriend_ && !bodyPresent_); }
- bool isFunction() const { return (result_ == Function); }
- bool isVariable() const { return (result_ == Variable); }
-
- public:
- ParseResult result_;
- Aggregate* parent_;
- QStringList parentPath_;
- QString name_;
- QString templateStuff_;
- Node::NodeType type_;
- Node::Access access_;
- FunctionNode::Metaness metaness_;
- bool bodyExpected_;
- bool bodyPresent_;
- bool isAttached_;
- bool isMacro_;
- bool isQPrivateSignal_;
- bool isQT_DEPRECATED_;
- bool isFriend_;
- bool isStatic_;
- bool isInline_;
- bool isExplicit_;
- bool isCompat_;
- bool isConst_;
- FunctionNode::Virtualness virtuality_;
- CodeChunk returnType_;
- Location location_;
- QVector<Parameter> pvect_;
-};
-
class PropertyNode : public LeafNode
{
public:
diff --git a/src/qdoc/qdocdatabase.cpp b/src/qdoc/qdocdatabase.cpp
index 795da4484..e3331a4f0 100644
--- a/src/qdoc/qdocdatabase.cpp
+++ b/src/qdoc/qdocdatabase.cpp
@@ -68,9 +68,8 @@ bool QDocDatabase::debug = false;
*/
QDocForest::~QDocForest()
{
- for (int i=0; i<searchOrder_.size(); ++i) {
+ for (int i=0; i<searchOrder_.size(); ++i)
delete searchOrder_.at(i);
- }
forest_.clear();
searchOrder_.clear();
indexSearchOrder_.clear();
@@ -1387,7 +1386,16 @@ void QDocDatabase::resolveNamespaces()
}
}
}
-
+#if 0
+/*!
+ */
+const Node* QDocDatabase::findFunctionNode(const QString& target,
+ const Node* relative,
+ Node::Genus genus)
+{
+ return forest_.findFunctionNode(target, relative, genus);
+}
+#endif
/*!
This function is called for autolinking to a \a type,
which could be a function return type or a parameter
@@ -1527,9 +1535,9 @@ void QDocDatabase::generateIndex(const QString& fileName,
}
/*!
- If there are open namespaces, search each one for a function
- node having the same function name as the function described
- in \a declData. The \a parentPath is a portion of the path
+ If there are open namespaces, search for the function node
+ having the same function name as the \a clone node in each
+ open namespace. The \a parentPath is a portion of the path
name provided with the function name at the point of
reference. \a parentPath is usually a class name. Return
the pointer to the function node if one is found in an
@@ -1539,13 +1547,13 @@ void QDocDatabase::generateIndex(const QString& fileName,
be removed.
*/
FunctionNode* QDocDatabase::findNodeInOpenNamespace(const QStringList& parentPath,
- const Declaration& declData)
+ const FunctionNode* clone)
{
FunctionNode* fn = 0;
if (!openNamespaces_.isEmpty()) {
foreach (const QString& t, openNamespaces_) {
QStringList path = t.split("::") + parentPath;
- fn = findFunctionNode(path, declData);
+ fn = findFunctionNode(path, clone);
if (fn)
break;
}
diff --git a/src/qdoc/qdocdatabase.h b/src/qdoc/qdocdatabase.h
index 941c7b61b..d51f9476d 100644
--- a/src/qdoc/qdocdatabase.h
+++ b/src/qdoc/qdocdatabase.h
@@ -302,10 +302,10 @@ class QDocDatabase
/*******************************************************************
The functions declared below are called for the current tree only.
********************************************************************/
- FunctionNode* findFunctionNode(const QStringList& parentPath, const Declaration& declData) {
- return primaryTree()->findFunctionNode(parentPath, declData);
+ FunctionNode* findFunctionNode(const QStringList& parentPath, const FunctionNode* clone) {
+ return primaryTree()->findFunctionNode(parentPath, clone);
}
- FunctionNode* findNodeInOpenNamespace(const QStringList& parentPath, const Declaration& declData);
+ FunctionNode* findNodeInOpenNamespace(const QStringList& parentPath, const FunctionNode* clone);
Node* findNodeInOpenNamespace(QStringList& path, Node::NodeType type);
const Node* checkForCollision(const QString& name) {
return primaryTree()->checkForCollision(name);
diff --git a/src/qdoc/qdocindexfiles.cpp b/src/qdoc/qdocindexfiles.cpp
index 25bfa259e..b3bf064fa 100644
--- a/src/qdoc/qdocindexfiles.cpp
+++ b/src/qdoc/qdocindexfiles.cpp
@@ -1267,7 +1267,7 @@ 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(false);
+ QString signature = functionNode->signature();
if (functionNode->isConst())
signature += " const";
writer.writeAttribute("signature", signature);
@@ -1483,9 +1483,9 @@ bool compareNodes(const Node* n1, const Node* n2)
else if (f1->isConst() > f2->isConst())
return false;
- if (f1->signature(false) < f2->signature(false))
+ if (f1->signature() < f2->signature())
return true;
- else if (f1->signature(false) > f2->signature(false))
+ else if (f1->signature() > f2->signature())
return false;
}
diff --git a/src/qdoc/qdoctagfiles.cpp b/src/qdoc/qdoctagfiles.cpp
index 26f5342c1..1210ac7c3 100644
--- a/src/qdoc/qdoctagfiles.cpp
+++ b/src/qdoc/qdoctagfiles.cpp
@@ -287,7 +287,7 @@ 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(false);
+ QString signature = functionNode->signature();
signature = signature.mid(signature.indexOf(QChar('('))).trimmed();
if (functionNode->isConst())
signature += " const";
diff --git a/src/qdoc/tokenizer.cpp b/src/qdoc/tokenizer.cpp
index b2cd906e6..987fff548 100644
--- a/src/qdoc/tokenizer.cpp
+++ b/src/qdoc/tokenizer.cpp
@@ -55,11 +55,10 @@ QT_BEGIN_NAMESPACE
*/
static const char *kwords[] = {
"char", "class", "const", "double", "enum", "explicit",
- "friend", "inline", "int", "long", "namespace", "noexcept",
- "operator", "private", "protected", "public", "short",
- "signals", "signed", "slots", "static", "struct", "template",
- "throw", "typedef", "typename", "union", "unsigned", "using",
- "virtual", "void", "volatile",
+ "friend", "inline", "int", "long", "namespace", "operator",
+ "private", "protected", "public", "short", "signals", "signed",
+ "slots", "static", "struct", "template", "typedef", "typename",
+ "union", "unsigned", "using", "virtual", "void", "volatile",
"__int64",
"Q_OBJECT",
"Q_OVERRIDE",
diff --git a/src/qdoc/tokenizer.h b/src/qdoc/tokenizer.h
index 456be7335..41a3ffd93 100644
--- a/src/qdoc/tokenizer.h
+++ b/src/qdoc/tokenizer.h
@@ -62,9 +62,9 @@ enum { Tok_Eoi, Tok_Ampersand, Tok_Aster, Tok_Caret, Tok_LeftParen,
Tok_Number, Tok_String, Tok_Doc, Tok_Comment, Tok_Ident, Tok_At,
Tok_char, Tok_class, Tok_const, Tok_double, Tok_enum,
Tok_explicit, Tok_friend, Tok_inline, Tok_int, Tok_long,
- Tok_namespace, Tok_noexcept, Tok_operator, Tok_private, Tok_protected,
+ Tok_namespace, Tok_operator, Tok_private, Tok_protected,
Tok_public, Tok_short, Tok_signals, Tok_signed, Tok_slots,
- Tok_static, Tok_struct, Tok_template, Tok_throw, Tok_typedef,
+ 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_Q_PROPERTY, Tok_Q_PRIVATE_PROPERTY, Tok_Q_DECLARE_SEQUENTIAL_ITERATOR,
diff --git a/src/qdoc/tree.cpp b/src/qdoc/tree.cpp
index 10b46f712..f8f88e6b9 100644
--- a/src/qdoc/tree.cpp
+++ b/src/qdoc/tree.cpp
@@ -102,8 +102,6 @@ Tree::Tree(const QString& camelCaseModuleName, QDocDatabase* qdb)
*/
Tree::~Tree()
{
- if (Generator::debugging())
- qDebug() << " Deleting tree:" << physicalModuleName_;
TargetMap::iterator i = nodesByTargetRef_.begin();
while (i != nodesByTargetRef_.end()) {
delete i.value();
@@ -123,8 +121,6 @@ Tree::~Tree()
++i;
}
}
- if (Generator::debugging())
- qDebug() << " Deleted tree:" << physicalModuleName_;
}
/* API members */
@@ -168,18 +164,17 @@ NamespaceNode* Tree::findNamespaceNode(const QStringList& path) const
}
/*!
- This function first ignores the \a declData parameter and
- searches for the parent node with \a parentPath. If that
- search is successful, it searches for a child node of the
- parent that matches the function described in \a declData.
- If it finds a match, it returns a pointer to the matching
- node.
+ This function first ignores the \a clone node and searches
+ for the parent node with \a parentPath. If that search is
+ successful, it searches for a child node of the parent that
+ matches the \a clone node. If it finds a node that is just
+ like the \a clone, it returns a pointer to the found node.
Apparently the search order is important here. Don't change
it unless you know what you are doing, or you will introduce
qdoc warnings.
*/
-FunctionNode* Tree::findFunctionNode(const QStringList& parentPath, const Declaration& declData)
+FunctionNode* Tree::findFunctionNode(const QStringList& parentPath, const FunctionNode* clone)
{
const Node* parent = findNamespaceNode(parentPath);
if (parent == 0)
@@ -188,7 +183,7 @@ FunctionNode* Tree::findFunctionNode(const QStringList& parentPath, const Declar
parent = findNode(parentPath, 0, 0, Node::DontCare);
if (parent == 0 || !parent->isAggregate())
return 0;
- return ((const Aggregate*)parent)->findFunctionNode(declData);
+ return ((const Aggregate*)parent)->findFunctionNode(clone);
}
@@ -556,15 +551,15 @@ void Tree::fixInheritance(NamespaceNode* rootNode)
/*!
*/
-FunctionNode* Tree::findVirtualFunctionInBaseClasses(ClassNode* cn, FunctionNode* virtualFunc)
+FunctionNode* Tree::findVirtualFunctionInBaseClasses(ClassNode* cn, FunctionNode* clone)
{
const QList<RelatedClass>& rc = cn->baseClasses();
QList<RelatedClass>::ConstIterator r = rc.constBegin();
while (r != rc.constEnd()) {
FunctionNode* func;
if ((*r).node_) {
- if (((func = findVirtualFunctionInBaseClasses((*r).node_, virtualFunc)) != 0 ||
- (func = (*r).node_->findFunctionNode(virtualFunc)) != 0)) {
+ if (((func = findVirtualFunctionInBaseClasses((*r).node_, clone)) != 0 ||
+ (func = (*r).node_->findFunctionNode(clone)) != 0)) {
if (func->virtualness() != FunctionNode::NonVirtual)
return func;
}
diff --git a/src/qdoc/tree.h b/src/qdoc/tree.h
index 649400e78..0558d693c 100644
--- a/src/qdoc/tree.h
+++ b/src/qdoc/tree.h
@@ -106,7 +106,7 @@ class Tree
Node* findNodeForInclude(const QStringList& path) const;
ClassNode* findClassNode(const QStringList& path, const Node* start = 0) const;
NamespaceNode* findNamespaceNode(const QStringList& path) const;
- FunctionNode* findFunctionNode(const QStringList& parentPath, const Declaration& declData);
+ FunctionNode* findFunctionNode(const QStringList& parentPath, const FunctionNode* clone);
const Node* findFunctionNode(const QString& target,
const QString& params,
const Node* relative,
@@ -173,7 +173,7 @@ class Tree
const NamespaceNode *root() const { return &root_; }
FunctionNode *findVirtualFunctionInBaseClasses(ClassNode *classe,
- FunctionNode *virtualFunc);
+ FunctionNode *clone);
NodeList allBaseClasses(const ClassNode *classe) const;
QString refForAtom(const Atom* atom);