diff options
Diffstat (limited to 'src/tools/qdoc')
-rw-r--r-- | src/tools/qdoc/cppcodeparser.cpp | 85 | ||||
-rw-r--r-- | src/tools/qdoc/cppcodeparser.h | 2 | ||||
-rw-r--r-- | src/tools/qdoc/node.cpp | 11 | ||||
-rw-r--r-- | src/tools/qdoc/node.h | 16 | ||||
-rw-r--r-- | src/tools/qdoc/qdocdatabase.cpp | 1 | ||||
-rw-r--r-- | src/tools/qdoc/tree.cpp | 26 | ||||
-rw-r--r-- | src/tools/qdoc/tree.h | 1 |
7 files changed, 118 insertions, 24 deletions
diff --git a/src/tools/qdoc/cppcodeparser.cpp b/src/tools/qdoc/cppcodeparser.cpp index 405be6f500..6cb86a7515 100644 --- a/src/tools/qdoc/cppcodeparser.cpp +++ b/src/tools/qdoc/cppcodeparser.cpp @@ -1692,35 +1692,76 @@ bool CppCodeParser::matchNamespaceDecl(InnerNode *parent) return matched && match(Tok_RightBrace); } -bool CppCodeParser::matchUsingDecl() +/*! + Match a C++ \c using clause. Return \c true if the match + is successful. Otherwise false. + + If the \c using clause is for a namespace, an open namespace + <is inserted for qdoc to look in to find things. + + If the \c using clause is a base class member function, the + member function is added to \a parent as an unresolved + \c using clause. + */ +bool CppCodeParser::matchUsingDecl(InnerNode* parent) { + bool usingNamespace = false; readToken(); // skip 'using' - // 'namespace' - if (tok != Tok_namespace) - return false; - - readToken(); - // identifier - if (tok != Tok_Ident) - return false; + if (tok == Tok_namespace) { + usingNamespace = true; + readToken(); + } + int openLeftAngles = 0; + int openLeftParens = 0; + bool usingOperator = false; QString name; - while (tok == Tok_Ident) { + while (tok != Tok_Semicolon) { + if ((tok != Tok_Ident) && (tok != Tok_Gulbrandsen)) { + if (tok == Tok_LeftAngle) { + ++openLeftAngles; + } + else if (tok == Tok_RightAngle) { + if (openLeftAngles <= 0) + return false; + --openLeftAngles; + } + else if (tok == Tok_Comma) { + if (openLeftAngles <= 0) + return false; + } + else if (tok == Tok_operator) { + usingOperator = true; + } + else if (tok == Tok_SomeOperator) { + if (!usingOperator) + return false; + } + else if (tok == Tok_LeftParen) { + ++openLeftParens; + } + else if (tok == Tok_RightParen) { + if (openLeftParens <= 0) + return false; + --openLeftParens; + } + else { + return false; + } + } name += lexeme(); readToken(); - if (tok == Tok_Semicolon) - break; - else if (tok != Tok_Gulbrandsen) - return false; - name += "::"; - readToken(); } - /* - So far, so good. We have 'using namespace Foo;'. - */ - qdb_->insertOpenNamespace(name); + if (usingNamespace) { + // 'using namespace Foo;'. + qdb_->insertOpenNamespace(name); + } + else if (parent && parent->isClass()) { + ClassNode* cn = static_cast<ClassNode*>(parent); + cn->addUnresolvedUsingClause(name); + } return true; } @@ -1961,7 +2002,7 @@ bool CppCodeParser::matchDeclList(InnerNode *parent) matchNamespaceDecl(parent); break; case Tok_using: - matchUsingDecl(); + matchUsingDecl(parent); break; case Tok_template: { @@ -2221,7 +2262,7 @@ bool CppCodeParser::matchDocsAndStuff() } } else if (tok == Tok_using) { - matchUsingDecl(); + matchUsingDecl(0); } else { QStringList parentPath; diff --git a/src/tools/qdoc/cppcodeparser.h b/src/tools/qdoc/cppcodeparser.h index dc5c8ca8bd..f9ddcab88c 100644 --- a/src/tools/qdoc/cppcodeparser.h +++ b/src/tools/qdoc/cppcodeparser.h @@ -127,7 +127,7 @@ protected: bool matchClassDecl(InnerNode *parent, const QString &templateStuff = QString()); bool matchNamespaceDecl(InnerNode *parent); - bool matchUsingDecl(); + bool matchUsingDecl(InnerNode* parent); bool matchEnumItem(InnerNode *parent, EnumNode *enume); bool matchEnumDecl(InnerNode *parent); bool matchTypedefDecl(InnerNode *parent); diff --git a/src/tools/qdoc/node.cpp b/src/tools/qdoc/node.cpp index f65b4ec942..e14ca4af3e 100644 --- a/src/tools/qdoc/node.cpp +++ b/src/tools/qdoc/node.cpp @@ -1415,6 +1415,17 @@ void ClassNode::addUnresolvedBaseClass(Access access, } /*! + Add an unresolved \c using clause to this class node's list + of \c using clauses. The unresolved \c using clause will be + resolved before the generate phase of qdoc. In an unresolved + \c using clause, the pointer to the function node is 0. + */ +void ClassNode::addUnresolvedUsingClause(const QString& signature) +{ + usingClauses_.append(UsingClause(signature)); +} + +/*! */ void ClassNode::fixBaseClasses() { diff --git a/src/tools/qdoc/node.h b/src/tools/qdoc/node.h index 8e25aac9c1..b6717b3b1b 100644 --- a/src/tools/qdoc/node.h +++ b/src/tools/qdoc/node.h @@ -479,6 +479,18 @@ struct RelatedClass QString signature_; }; +struct UsingClause +{ + UsingClause() { } + UsingClause(const QString& signature) : node_(0), signature_(signature) { } + const QString& signature() const { return signature_; } + const Node* node() { return node_; } + void setNode(const Node* n) { node_ = n; } + + const Node* node_; + QString signature_; +}; + class ClassNode : public InnerNode { public: @@ -493,16 +505,19 @@ public: void addResolvedBaseClass(Access access, ClassNode* node); void addDerivedClass(Access access, ClassNode* node); void addUnresolvedBaseClass(Access access, const QStringList& path, const QString& signature); + void addUnresolvedUsingClause(const QString& signature); void fixBaseClasses(); void fixPropertyUsingBaseClasses(PropertyNode* pn); QList<RelatedClass>& baseClasses() { return bases_; } QList<RelatedClass>& derivedClasses() { return derived_; } QList<RelatedClass>& ignoredBaseClasses() { return ignoredBases_; } + QList<UsingClause>& usingClauses() { return usingClauses_; } const QList<RelatedClass> &baseClasses() const { return bases_; } const QList<RelatedClass> &derivedClasses() const { return derived_; } const QList<RelatedClass> &ignoredBaseClasses() const { return ignoredBases_; } + const QList<UsingClause>& usingClauses() const { return usingClauses_; } QString serviceName() const { return sname; } void setServiceName(const QString& value) { sname = value; } @@ -517,6 +532,7 @@ private: QList<RelatedClass> bases_; QList<RelatedClass> derived_; QList<RelatedClass> ignoredBases_; + QList<UsingClause> usingClauses_; bool abstract_; bool wrapper_; QString sname; diff --git a/src/tools/qdoc/qdocdatabase.cpp b/src/tools/qdoc/qdocdatabase.cpp index 2f7c2eaeb7..75295613f7 100644 --- a/src/tools/qdoc/qdocdatabase.cpp +++ b/src/tools/qdoc/qdocdatabase.cpp @@ -1331,6 +1331,7 @@ void QDocDatabase::resolveStuff() resolveQmlInheritance(primaryTreeRoot()); //primaryTree()->resolveTargets(primaryTreeRoot()); primaryTree()->resolveCppToQmlLinks(); + primaryTree()->resolveUsingClauses(); } /*! diff --git a/src/tools/qdoc/tree.cpp b/src/tools/qdoc/tree.cpp index ed4b4e3979..6393ad4e6f 100644 --- a/src/tools/qdoc/tree.cpp +++ b/src/tools/qdoc/tree.cpp @@ -499,6 +499,29 @@ void Tree::resolveCppToQmlLinks() } /*! + For each C++ class node, resolve any \c using clauses + that appeared in the class declaration. + */ +void Tree::resolveUsingClauses() +{ + foreach (Node* child, root_.childNodes()) { + if (child->isClass()) { + ClassNode* cn = static_cast<ClassNode*>(child); + QList<UsingClause>& usingClauses = cn->usingClauses(); + QList<UsingClause>::iterator uc = usingClauses.begin(); + while (uc != usingClauses.end()) { + if (!(*uc).node()) { + const Node* n = qdb_->findFunctionNode((*uc).signature(), cn, Node::CPP); + if (n) + (*uc).setNode(n); + } + ++uc; + } + } + } +} + +/*! */ void Tree::fixInheritance(NamespaceNode* rootNode) { @@ -1427,7 +1450,8 @@ void Tree::insertQmlType(const QString& key, QmlTypeNode* n) const Node* Tree::findFunctionNode(const QString& target, const Node* relative, Node::Genus genus) { QString t = target; - t.chop(2); + if (t.endsWith("()")) + t.chop(2); QStringList path = t.split("::"); const FunctionNode* fn = findFunctionNode(path, relative, SearchBaseClasses, genus); if (fn && fn->metaness() != FunctionNode::MacroWithoutParams) diff --git a/src/tools/qdoc/tree.h b/src/tools/qdoc/tree.h index 2e6f766770..67063ef86a 100644 --- a/src/tools/qdoc/tree.h +++ b/src/tools/qdoc/tree.h @@ -153,6 +153,7 @@ class Tree void resolveInheritanceHelper(int pass, ClassNode* cn); void resolveProperties(); void resolveCppToQmlLinks(); + void resolveUsingClauses(); void fixInheritance(NamespaceNode *rootNode = 0); NamespaceNode *root() { return &root_; } |