/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

/*
  cppcodeparser.cpp
*/

#include <qfile.h>

#include <stdio.h>
#include <errno.h>

#include "codechunk.h"
#include "config.h"
#include "cppcodeparser.h"
#include "tokenizer.h"
#include "tree.h"

QT_BEGIN_NAMESPACE

/* qmake ignore Q_OBJECT */

#define COMMAND_CLASS                   Doc::alias("class")
#define COMMAND_CONTENTSPAGE            Doc::alias("contentspage")
#define COMMAND_ENUM                    Doc::alias("enum")
#define COMMAND_EXAMPLE                 Doc::alias("example")
#define COMMAND_EXTERNALPAGE            Doc::alias("externalpage")
#define COMMAND_FILE                    Doc::alias("file") // ### don't document
#define COMMAND_FN                      Doc::alias("fn")
#define COMMAND_GROUP                   Doc::alias("group")
#define COMMAND_HEADERFILE              Doc::alias("headerfile")
#define COMMAND_INDEXPAGE               Doc::alias("indexpage")
#define COMMAND_INHEADERFILE            Doc::alias("inheaderfile") // ### don't document
#define COMMAND_MACRO                   Doc::alias("macro")
#define COMMAND_MODULE                  Doc::alias("module") // ### don't document
#define COMMAND_NAMESPACE               Doc::alias("namespace")
#define COMMAND_OVERLOAD                Doc::alias("overload")
#define COMMAND_NEXTPAGE                Doc::alias("nextpage")
#define COMMAND_PAGE                    Doc::alias("page")
#define COMMAND_PREVIOUSPAGE            Doc::alias("previouspage")
#define COMMAND_PROPERTY                Doc::alias("property")
#define COMMAND_REIMP                   Doc::alias("reimp")
#define COMMAND_RELATES                 Doc::alias("relates")
#define COMMAND_SERVICE                 Doc::alias("service")
#define COMMAND_STARTPAGE               Doc::alias("startpage")
#define COMMAND_TYPEDEF                 Doc::alias("typedef")
#define COMMAND_VARIABLE                Doc::alias("variable")

#ifdef QDOC_QML
#define COMMAND_QMLCLASS                Doc::alias("qmlclass")
#define COMMAND_QMLPROPERTY             Doc::alias("qmlproperty")
#define COMMAND_QMLATTACHEDPROPERTY     Doc::alias("qmlattachedproperty")
#define COMMAND_QMLINHERITS             Doc::alias("inherits")
#define COMMAND_QMLSIGNAL               Doc::alias("qmlsignal")
#define COMMAND_QMLATTACHEDSIGNAL       Doc::alias("qmlattachedsignal")
#define COMMAND_QMLMETHOD               Doc::alias("qmlmethod")
#define COMMAND_QMLATTACHEDMETHOD       Doc::alias("qmlattachedmethod")
#define COMMAND_QMLDEFAULT              Doc::alias("default")
#define COMMAND_QMLBASICTYPE            Doc::alias("qmlbasictype")
#endif

#define COMMAND_AUDIENCE                Doc::alias("audience")
#define COMMAND_CATEGORY                Doc::alias("category")
#define COMMAND_PRODNAME                Doc::alias("prodname")
#define COMMAND_COMPONENT               Doc::alias("component")
#define COMMAND_AUTHOR                  Doc::alias("author")
#define COMMAND_PUBLISHER               Doc::alias("publisher")
#define COMMAND_COPYRYEAR               Doc::alias("copyryear")
#define COMMAND_COPYRHOLDER             Doc::alias("copyrholder")
#define COMMAND_PERMISSIONS             Doc::alias("permissions")
#define COMMAND_LIFECYCLEVERSION        Doc::alias("lifecycleversion")
#define COMMAND_LIFECYCLEWSTATUS        Doc::alias("lifecyclestatus")
#define COMMAND_LICENSEYEAR             Doc::alias("licenseyear")
#define COMMAND_LICENSENAME             Doc::alias("licensename")
#define COMMAND_LICENSEDESCRIPTION      Doc::alias("licensedescription")
#define COMMAND_RELEASEDATE             Doc::alias("releasedate")

QStringList CppCodeParser::exampleFiles;
QStringList CppCodeParser::exampleDirs;

static void extractPageLinkAndDesc(const QString &arg,
                                   QString *link,
                                   QString *desc)
{
    QRegExp bracedRegExp("\\{([^{}]*)\\}(?:\\{([^{}]*)\\})?");

    if (bracedRegExp.exactMatch(arg)) {
        *link = bracedRegExp.cap(1);
        *desc = bracedRegExp.cap(2);
        if (desc->isEmpty())
            *desc = *link;
    }
    else {
        int spaceAt = arg.indexOf(" ");
        if (arg.contains(".html") && spaceAt != -1) {
            *link = arg.left(spaceAt).trimmed();
            *desc = arg.mid(spaceAt).trimmed();
        }
        else {
            *link = arg;
            *desc = arg;
        }
    }
}

static void setLink(Node *node, Node::LinkType linkType, const QString &arg)
{
    QString link;
    QString desc;
    extractPageLinkAndDesc(arg, &link, &desc);
    node->setLink(linkType, link, desc);
}

/*
    This is used for fuzzy matching only, which in turn is only used
    for Qt Jambi.
*/
static QString cleanType(const QString &type, const Tree *tree)
{
    QString result = type;
    result.replace("qlonglong", "long long");
    result.replace("qulonglong", "unsigned long long");
    result.replace("qreal", "double");
    result.replace(QRegExp("\\bu(int|short|char|long)\\b"), "unsigned \\1");
    result.replace("QRgb", "unsigned int");
    result.replace(" >", ">");
    result.remove(" const[]");
    result.replace("QStringList<QString>", "QStringList");
    result.replace("qint8", "char");
    result.replace("qint16", "short");
    result.replace("qint32", "int");
    result.replace("qint64", "long long");
    result.replace("quint8", "unsigned char");
    result.replace("quint16", "unsigned short");
    result.replace("quint32", "unsigned int");
    result.replace("quint64", "unsigned long long");

    if (result.contains("QFlags")) {
        QRegExp regExp("QFlags<(((?:[^<>]+::)*)([^<>:]+))>");
        int pos = 0;
        while ((pos = result.indexOf(regExp, pos)) != -1) {
            // we assume that the path for the associated enum
            // is the same as for the flag typedef
            QStringList path = regExp.cap(2).split("::",
                                                   QString::SkipEmptyParts);
            const EnumNode *enume = static_cast<const EnumNode *>(
                             tree->findNode(QStringList(path) << regExp.cap(3),
                                            Node::Enum));
            if (enume && enume->flagsType())
                result.replace(pos, regExp.matchedLength(),
                 (QStringList(path) << enume->flagsType()->name()).join("::"));
            ++pos;
        }
    }
    if (result.contains("::")) {
        // remove needless (and needful) class prefixes
        QRegExp regExp("[A-Za-z0-9_]+::");
        result.replace(regExp, "");
    }
    return result;
}

/*!
  The constructor initializes some regular expressions
  and calls reset().
 */
CppCodeParser::CppCodeParser()
    : varComment("/\\*\\s*([a-zA-Z_0-9]+)\\s*\\*/"), sep("(?:<[^>]+>)?::")
{
    reset(0);
}

/*!
  The destructor is trivial.
 */
CppCodeParser::~CppCodeParser()
{
    // nothing.
}

/*!
  The constructor initializes a map of special node types
  for identifying important nodes. And it initializes
  some filters for identifying certain kinds of files.
 */
void CppCodeParser::initializeParser(const Config &config)
{
    CodeParser::initializeParser(config);

    nodeTypeMap.insert(COMMAND_NAMESPACE, Node::Namespace);
    nodeTypeMap.insert(COMMAND_CLASS, Node::Class);
    nodeTypeMap.insert(COMMAND_SERVICE, Node::Class);
    nodeTypeMap.insert(COMMAND_ENUM, Node::Enum);
    nodeTypeMap.insert(COMMAND_TYPEDEF, Node::Typedef);
    nodeTypeMap.insert(COMMAND_PROPERTY, Node::Property);
    nodeTypeMap.insert(COMMAND_VARIABLE, Node::Variable);

    exampleFiles = config.getStringList(CONFIG_EXAMPLES);
    exampleDirs = config.getStringList(CONFIG_EXAMPLEDIRS);
    QStringList exampleFilePatterns = config.getStringList(
        CONFIG_EXAMPLES + Config::dot + CONFIG_FILEEXTENSIONS);

    if (!exampleFilePatterns.isEmpty())
        exampleNameFilter = exampleFilePatterns.join(" ");
    else
        exampleNameFilter = "*.cpp *.h *.js *.xq *.svg *.xml *.ui";

    QStringList exampleImagePatterns = config.getStringList(
        CONFIG_EXAMPLES + Config::dot + CONFIG_IMAGEEXTENSIONS);

    if (!exampleImagePatterns.isEmpty())
        exampleImageFilter = exampleImagePatterns.join(" ");
    else
        exampleImageFilter = "*.png";
}

/*!
  Clear the map of common node types and call
  the same function in the base class.
 */
void CppCodeParser::terminateParser()
{
    nodeTypeMap.clear();
    CodeParser::terminateParser();
}

/*!
  Returns "Cpp".
 */
QString CppCodeParser::language()
{
    return "Cpp";
}

/*!
  Returns a list of extensions for header files.
 */
QStringList CppCodeParser::headerFileNameFilter()
{
    return QStringList() << "*.ch" << "*.h" << "*.h++" << "*.hh" << "*.hpp" << "*.hxx";
}

/*!
  Returns a list of extensions for source files, i.e. not
  header files.
 */
QStringList CppCodeParser::sourceFileNameFilter()
{
    return QStringList() << "*.c++" << "*.cc" << "*.cpp" << "*.cxx" << "*.mm";
}

/*!
  Parse the C++ header file identified by \a filePath
  and add the parsed contents to the big \a tree. The
  \a location is used for reporting errors.
 */
void CppCodeParser::parseHeaderFile(const Location& location,
                                    const QString& filePath,
                                    Tree *tree)
{
    QFile in(filePath);
    if (!in.open(QIODevice::ReadOnly)) {
        location.error(tr("Cannot open C++ header file '%1'").arg(filePath));
        return;
    }

    reset(tree);
    Location fileLocation(filePath);
    Tokenizer fileTokenizer(fileLocation, in);
    tokenizer = &fileTokenizer;
    readToken();
    matchDeclList(tree->root());
    if (!fileTokenizer.version().isEmpty())
        tree->setVersion(fileTokenizer.version());
    in.close();

    if (fileLocation.fileName() == "qiterator.h")
        parseQiteratorDotH(location, filePath);
}

/*!
  Get ready to parse the C++ cpp file identified by \a filePath
  and add its parsed contents to the big \a tree. \a location is
  used for reporting errors.

  Call matchDocsAndStuff() to do all the parsing and tree building.
 */
void CppCodeParser::parseSourceFile(const Location& location,
                                    const QString& filePath,
                                    Tree *tree)
{
    QFile in(filePath);
    if (!in.open(QIODevice::ReadOnly)) {
        location.error(tr("Cannot open C++ source file '%1' (%2)").arg(filePath).arg(strerror(errno)));
        return;
    }

    reset(tree);
    Location fileLocation(filePath);
    Tokenizer fileTokenizer(fileLocation, in);
    tokenizer = &fileTokenizer;
    readToken();
    usedNamespaces.clear();
    matchDocsAndStuff();
    in.close();
}

/*!
  This is called after all the header files have been parsed.
  I think the most important thing it does is resolve class
  inheritance links in the tree. But it also initializes a
  bunch of stuff.
 */
void CppCodeParser::doneParsingHeaderFiles(Tree *tree)
{
    tree->resolveInheritance();

    QMapIterator<QString, QString> i(sequentialIteratorClasses);
    while (i.hasNext()) {
        i.next();
        instantiateIteratorMacro(i.key(),
                                 i.value(),
                                 sequentialIteratorDefinition,
                                 tree);
    }
    i = mutableSequentialIteratorClasses;
    while (i.hasNext()) {
        i.next();
        instantiateIteratorMacro(i.key(),
                                 i.value(),
                                 mutableSequentialIteratorDefinition,
                                 tree);
    }
    i = associativeIteratorClasses;
    while (i.hasNext()) {
        i.next();
        instantiateIteratorMacro(i.key(),
                                 i.value(),
                                 associativeIteratorDefinition,
                                 tree);
    }
    i = mutableAssociativeIteratorClasses;
    while (i.hasNext()) {
        i.next();
        instantiateIteratorMacro(i.key(),
                                 i.value(),
                                 mutableAssociativeIteratorDefinition,
                                 tree);
    }
    sequentialIteratorDefinition.clear();
    mutableSequentialIteratorDefinition.clear();
    associativeIteratorDefinition.clear();
    mutableAssociativeIteratorDefinition.clear();
    sequentialIteratorClasses.clear();
    mutableSequentialIteratorClasses.clear();
    associativeIteratorClasses.clear();
    mutableAssociativeIteratorClasses.clear();
}

/*!
  This is called after all the source files (i.e., not the
  header files) have been parsed. It traverses the tree to
  resolve property links, normalize overload signatures, and
  do other housekeeping of the tree.
 */
void CppCodeParser::doneParsingSourceFiles(Tree *tree)
{
    tree->root()->makeUndocumentedChildrenInternal();
    tree->root()->normalizeOverloads();
    tree->fixInheritance();
    tree->resolveProperties();
}

/*!
  This function searches the \a tree to find a FunctionNode
  for a function with the signature \a synopsis. If the
  \a relative node is provided, the search begins there. If
  \a fuzzy is true, base classes are searched. The function
  node is returned, if found.
 */
const FunctionNode *CppCodeParser::findFunctionNode(const QString& synopsis,
                                                    Tree *tree,
                                                    Node *relative,
                                                    bool fuzzy)
{
    QStringList parentPath;
    FunctionNode *clone;
    FunctionNode *func = 0;
    int flags = fuzzy ? int(Tree::SearchBaseClasses) : 0;

    reset(tree);
    if (makeFunctionNode(synopsis, &parentPath, &clone)) {
        func = tree->findFunctionNode(parentPath, clone, relative, flags);

        /*
            This is necessary because Roberto's parser resolves typedefs.
        */
        if (!func && fuzzy) {
            func = tre->findFunctionNode(parentPath +
                                         QStringList(clone->name()),
                                         relative,
                                         flags);
            if (!func && clone->name().contains('_')) {
                QStringList path = parentPath;
                path << clone->name().split('_');
                func = tre->findFunctionNode(path, relative, flags);
            }

            if (func) {
                NodeList overloads = func->parent()->overloads(func->name());
                NodeList candidates;
                for (int i = 0; i < overloads.count(); ++i) {
                    FunctionNode *overload = static_cast<FunctionNode *>(overloads.at(i));
                    if (overload->status() != Node::Compat
                            && overload->parameters().count() == clone->parameters().count()
                            && !overload->isConst() == !clone->isConst())
                        candidates << overload;
                }
                if (candidates.count() == 0)
                    return 0;

                /*
                    There's only one function with the correct number
                    of parameters. That must be the one.
                */
                if (candidates.count() == 1)
                    return static_cast<FunctionNode *>(candidates.first());

                overloads = candidates;
                candidates.clear();
                for (int i = 0; i < overloads.count(); ++i) {
                    FunctionNode *overload = static_cast<FunctionNode *>(overloads.at(i));
                    QList<Parameter> params1 = overload->parameters();
                    QList<Parameter> params2 = clone->parameters();

                    int j;
                    for (j = 0; j < params1.count(); ++j) {
                        if (!params2.at(j).name().startsWith(params1.at(j).name()))
                            break;
                    }
                    if (j == params1.count())
                        candidates << overload;
                }

                /*
                    There are several functions with the correct
                    parameter count, but only one has the correct
                    parameter names.
                */
                if (candidates.count() == 1)
                    return static_cast<FunctionNode *>(candidates.first());

                candidates.clear();
                for (int i = 0; i < overloads.count(); ++i) {
                    FunctionNode *overload = static_cast<FunctionNode *>(overloads.at(i));
                    QList<Parameter> params1 = overload->parameters();
                    QList<Parameter> params2 = clone->parameters();

                    int j;
                    for (j = 0; j < params1.count(); ++j) {
                        if (params1.at(j).rightType() != params2.at(j).rightType())
                            break;

                        if (cleanType(params1.at(j).leftType(), tree)
                                != cleanType(params2.at(j).leftType(), tree))
                            break;
                    }
                    if (j == params1.count())
                        candidates << overload;
                }


                /*
                    There are several functions with the correct
                    parameter count, but only one has the correct
                    types, loosely compared.
                */
                if (candidates.count() == 1)
                    return static_cast<FunctionNode *>(candidates.first());

                return 0;
            }
        }
        delete clone;
    }
    return func;
}

/*!
  Returns the set of strings reopresenting the topic commands.
 */
QSet<QString> CppCodeParser::topicCommands()
{
    return QSet<QString>() << COMMAND_CLASS
                           << COMMAND_ENUM
                           << COMMAND_EXAMPLE
                           << COMMAND_EXTERNALPAGE
                           << COMMAND_FILE
                           << COMMAND_FN
                           << COMMAND_GROUP
                           << COMMAND_HEADERFILE
                           << COMMAND_MACRO
                           << COMMAND_MODULE
                           << COMMAND_NAMESPACE
                           << COMMAND_PAGE
                           << COMMAND_PROPERTY
                           << COMMAND_SERVICE
                           << COMMAND_TYPEDEF
#ifdef QDOC_QML
                           << COMMAND_VARIABLE
                           << COMMAND_QMLCLASS
                           << COMMAND_QMLPROPERTY
                           << COMMAND_QMLATTACHEDPROPERTY
                           << COMMAND_QMLSIGNAL
                           << COMMAND_QMLATTACHEDSIGNAL
                           << COMMAND_QMLMETHOD
                           << COMMAND_QMLATTACHEDMETHOD
                           << COMMAND_QMLBASICTYPE;
#else
                           << COMMAND_VARIABLE;
#endif
}

/*!
  Process the topic \a command in context \a doc with argument \a arg.
 */
Node *CppCodeParser::processTopicCommand(const Doc& doc,
                                         const QString& command,
                                         const QString& arg)
{
    if (command == COMMAND_FN) {
        QStringList parentPath;
        FunctionNode *func = 0;
        FunctionNode *clone = 0;

        if (!makeFunctionNode(arg, &parentPath, &clone) &&
             !makeFunctionNode("void " + arg, &parentPath, &clone)) {
            doc.location().warning(tr("Invalid syntax in '\\%1'")
                                    .arg(COMMAND_FN));
        }
        else {
            if (!usedNamespaces.isEmpty()) {
                foreach (const QString &usedNamespace, usedNamespaces) {
                    QStringList newPath = usedNamespace.split("::") + parentPath;
                    func = tre->findFunctionNode(newPath, clone);
                    if (func)
                        break;
                }
            }
            // Search the root namespace if no match was found.
            if (func == 0)
                func = tre->findFunctionNode(parentPath, clone);

            if (func == 0) {
                if (parentPath.isEmpty() && !lastPath.isEmpty())
                    func = tre->findFunctionNode(lastPath, clone);
                if (func == 0) {
                    doc.location().warning(tr("Cannot find '%1' in '\\%2'")
                                           .arg(clone->name() + "(...)")
                                           .arg(COMMAND_FN),
                                           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 {
                    doc.location().warning(tr("Missing '%1::' for '%2' in '\\%3'")
                                            .arg(lastPath.join("::"))
                                            .arg(clone->name() + "()")
                                            .arg(COMMAND_FN));
                }
            }
            else {
                lastPath = parentPath;
            }
            if (func) {
                func->borrowParameterNames(clone);
                func->setParentPath(clone->parentPath());
            }
            delete clone;
        }
        return func;
    }
    else if (command == COMMAND_MACRO) {
        QStringList parentPath;
        FunctionNode *func = 0;

        if (makeFunctionNode(arg, &parentPath, &func, tre->root())) {
            if (!parentPath.isEmpty()) {
                doc.location().warning(tr("Invalid syntax in '\\%1'")
                                        .arg(COMMAND_MACRO));
                delete func;
                func = 0;
            }
            else {
                func->setMetaness(FunctionNode::MacroWithParams);
                QList<Parameter> params = func->parameters();
                for (int i = 0; i < params.size(); ++i) {
                    Parameter &param = params[i];
                    if (param.name().isEmpty() && !param.leftType().isEmpty()
                            && param.leftType() != "...")
                        param = Parameter("", "", param.leftType());
                }
                func->setParameters(params);
            }
            return func;
        }
        else if (QRegExp("[A-Za-z_][A-Za-z0-9_]+").exactMatch(arg)) {
            func = new FunctionNode(tre->root(), arg);
            func->setAccess(Node::Public);
            func->setLocation(doc.location());
            func->setMetaness(FunctionNode::MacroWithoutParams);
        }
        else {
            doc.location().warning(tr("Invalid syntax in '\\%1'")
                                    .arg(COMMAND_MACRO));

        }
        return func;
    }
    else if (nodeTypeMap.contains(command)) {
        /*
          The command was neither "fn" nor "macro" .
         */
        // ### split(" ") hack is there to support header file syntax
        QStringList paths = arg.split(" ");
        QStringList path = paths[0].split("::");
        Node *node = 0;
        if (!usedNamespaces.isEmpty()) {
            foreach (const QString &usedNamespace, usedNamespaces) {
                QStringList newPath = usedNamespace.split("::") + path;
                node = tre->findNode(newPath, nodeTypeMap[command]);
                if (node) {
                    path = newPath;
                    break;
                }
            }
        }
        // Search the root namespace if no match was found.
        if (node == 0)
            node = tre->findNode(path, nodeTypeMap[command]);

        if (node == 0) {
            doc.location().warning(tr("Cannot find '%1' specified with '\\%2' in any header file")
                                   .arg(arg).arg(command));
            lastPath = path;

        }
        else if (command == COMMAND_SERVICE) {
            // If the command is "\service", then we need to tag the
            // class with the actual service name.
            QStringList args = arg.split(" ");
            if (args.size() > 1) {
                ClassNode *cnode = static_cast<ClassNode *>(node);
                cnode->setServiceName(args[1]);
                cnode->setHideFromMainList(true);
            }
        }
        else if (node->isInnerNode()) {
            if (path.size() > 1) {
                path.pop_back();
                usedNamespaces.insert(path.join("::"));
            }
        }

        if (command == COMMAND_CLASS) {
            if (paths.size() > 1) {
                if (!paths[1].endsWith(".h")) {
                    ClassNode*cnode = static_cast<ClassNode*>(node);
                    cnode->setQmlElement(paths[1]);
                }
            }
        }
        return node;
    }
    else if (command == COMMAND_EXAMPLE) {
        FakeNode *fake = new FakeNode(tre->root(), arg, Node::Example);
        createExampleFileNodes(fake);
        return fake;
    }
    else if (command == COMMAND_EXTERNALPAGE) {
        return new FakeNode(tre->root(), arg, Node::ExternalPage);
    }
    else if (command == COMMAND_FILE) {
        return new FakeNode(tre->root(), arg, Node::File);
    }
    else if (command == COMMAND_GROUP) {
        return new FakeNode(tre->root(), arg, Node::Group);
    }
    else if (command == COMMAND_HEADERFILE) {
        return new FakeNode(tre->root(), arg, Node::HeaderFile);
    }
    else if (command == COMMAND_MODULE) {
        return new FakeNode(tre->root(), arg, Node::Module);
    }
    else if (command == COMMAND_PAGE) {
        return new FakeNode(tre->root(), arg, Node::Page);
    }
#ifdef QDOC_QML
    else if (command == COMMAND_QMLCLASS) {
        const ClassNode* classNode = 0;
        QStringList names = arg.split(" ");
        if (names.size() > 1) {
            Node* n = tre->findNode(names[1].split("::"),Node::Class);
            if (n)
                classNode = static_cast<const ClassNode*>(n);
        }
        if (names[0].startsWith("Qt"))
            return new QmlClassNode(tre->root(), QLatin1String("QML:")+names[0], classNode);
        else
            return new QmlClassNode(tre->root(), names[0], classNode);
    }
    else if (command == COMMAND_QMLBASICTYPE) {
        return new QmlBasicTypeNode(tre->root(), arg);
    }
    else if ((command == COMMAND_QMLSIGNAL) ||
             (command == COMMAND_QMLMETHOD) ||
             (command == COMMAND_QMLATTACHEDSIGNAL) ||
             (command == COMMAND_QMLATTACHEDMETHOD)) {
        QString element;
        QString type;
        QmlClassNode* qmlClass = 0;
        if (splitQmlMethodArg(doc,arg,type,element)) {
            if (element.startsWith(QLatin1String("Qt")))
                element = QLatin1String("QML:") + element;
            Node* n = tre->findNode(QStringList(element),Node::Fake);
            if (n && n->subType() == Node::QmlClass) {
                qmlClass = static_cast<QmlClassNode*>(n);
                if (command == COMMAND_QMLSIGNAL)
                    return makeFunctionNode(doc,arg,qmlClass,Node::QmlSignal,false,COMMAND_QMLSIGNAL);
                else if (command == COMMAND_QMLATTACHEDSIGNAL)
                    return makeFunctionNode(doc,arg,qmlClass,Node::QmlSignal,true,COMMAND_QMLATTACHEDSIGNAL);
                else if (command == COMMAND_QMLMETHOD)
                    return makeFunctionNode(doc,arg,qmlClass,Node::QmlMethod,false,COMMAND_QMLMETHOD);
                else if (command == COMMAND_QMLATTACHEDMETHOD)
                    return makeFunctionNode(doc,arg,qmlClass,Node::QmlMethod,true,COMMAND_QMLATTACHEDMETHOD);
                else
                    return 0; // never get here.
            }
        }
    }
#endif
    return 0;
}

#ifdef QDOC_QML

/*!
  A QML property argument has the form...

  <type> <element>::<name>

  This function splits the argument into those three
  parts, sets \a type, \a element, and \a name,
  and returns true. If any of the parts isn't found,
  a qdoc warning is output and false is returned.
 */
bool CppCodeParser::splitQmlPropertyArg(const Doc& doc,
                                        const QString& arg,
                                        QString& type,
                                        QString& element,
                                        QString& name)
{
    QStringList blankSplit = arg.split(" ");
    if (blankSplit.size() > 1) {
        type = blankSplit[0];
        QStringList colonSplit(blankSplit[1].split("::"));
        if (colonSplit.size() > 1) {
            element = colonSplit[0];
            name = colonSplit[1];
            return true;
        }
        else
            doc.location().warning(tr("Missing parent QML element name"));
    }
    else
        doc.location().warning(tr("Missing property type"));
    return false;
}

/*!
  A QML signal or method argument has the form...

  <type> <element>::<name>(<param>, <param>, ...)

  This function splits the argument into those two
  parts, sets \a element, and \a name, and returns
  true. If either of the parts isn't found, a debug
  message is output and false is returned.
 */
bool CppCodeParser::splitQmlMethodArg(const Doc& doc,
                                      const QString& arg,
                                      QString& type,
                                      QString& element)
{
    QStringList colonSplit(arg.split("::"));
    if (colonSplit.size() > 1) {
        QStringList blankSplit = colonSplit[0].split(" ");
        if (blankSplit.size() > 1) {
            type = blankSplit[0];
            element = blankSplit[1];
        }
        else {
            type = QString("");
            element = colonSplit[0];
        }
        return true;
    }
    else
        doc.location().warning(tr("Missing parent QML element or method signature"));
    return false;
}

/*!
  Process the topic \a command group with arguments \a args.

  Currently, this function is called only for \e{qmlproperty}
  and \e{qmlattachedproperty}.
 */
Node *CppCodeParser::processTopicCommandGroup(const Doc& doc,
                                              const QString& command,
                                              const QStringList& args)
{
    QmlPropGroupNode* qmlPropGroup = 0;
    if ((command == COMMAND_QMLPROPERTY) ||
        (command == COMMAND_QMLATTACHEDPROPERTY)) {
        QString type;
        QString element;
        QString property;
        bool attached = (command == COMMAND_QMLATTACHEDPROPERTY);
        QStringList::ConstIterator arg = args.begin();
        if (splitQmlPropertyArg(doc,(*arg),type,element,property)) {
            Node* n = tre->findNode(QStringList(element),Node::Fake);
            if (n && n->subType() == Node::QmlClass) {
                QmlClassNode* qmlClass = static_cast<QmlClassNode*>(n);
                if (qmlClass)
                    qmlPropGroup = new QmlPropGroupNode(qmlClass,
                                                        property,
                                                        attached);
            }
        }
        if (qmlPropGroup) {
            const ClassNode *correspondingClass = static_cast<const QmlClassNode*>(qmlPropGroup->parent())->classNode();
            QmlPropertyNode *qmlPropNode = new QmlPropertyNode(qmlPropGroup,property,type,attached);

            const PropertyNode *correspondingProperty = 0;
            if (correspondingClass) {
                correspondingProperty = qmlPropNode->correspondingProperty(tre);
            }
            if (correspondingProperty) {
                bool writableList = type.startsWith("list") && correspondingProperty->dataType().endsWith('*');
                qmlPropNode->setWritable(writableList || correspondingProperty->isWritable());
            }
            ++arg;
            while (arg != args.end()) {
                if (splitQmlPropertyArg(doc,(*arg),type,element,property)) {
                    QmlPropertyNode* qmlPropNode = new QmlPropertyNode(qmlPropGroup,
                                                                       property,
                                                                       type,
                                                                       attached);
                    if (correspondingProperty) {
                        bool writableList = type.startsWith("list") && correspondingProperty->dataType().endsWith('*');
                        qmlPropNode->setWritable(writableList || correspondingProperty->isWritable());
                    }
                }
                ++arg;
            }
        }
    }
    return qmlPropGroup;
}
#endif

/*!
  Returns the set of strings representing the common metacommands
  plus some other metacommands.
 */
QSet<QString> CppCodeParser::otherMetaCommands()
{
    return commonMetaCommands() << COMMAND_INHEADERFILE
                                << COMMAND_OVERLOAD
                                << COMMAND_REIMP
                                << COMMAND_RELATES
                                << COMMAND_CONTENTSPAGE
                                << COMMAND_NEXTPAGE
                                << COMMAND_PREVIOUSPAGE
                                << COMMAND_INDEXPAGE
#ifdef QDOC_QML
                                << COMMAND_STARTPAGE
                                << COMMAND_QMLINHERITS
                                << COMMAND_QMLDEFAULT;
#else
                                << COMMAND_STARTPAGE;
#endif
}

/*!
  Process the metacommand \a command in the context of the
  \a node associated with the topic command and the \a doc.
  \a arg is the argument to the metacommand.
 */
void CppCodeParser::processOtherMetaCommand(const Doc& doc,
                                            const QString& command,
                                            const QString& arg,
                                            Node *node)
{
    if (command == COMMAND_INHEADERFILE) {
        if (node != 0 && node->isInnerNode()) {
            ((InnerNode *) node)->addInclude(arg);
        }
        else {
            doc.location().warning(tr("Ignored '\\%1'")
                                   .arg(COMMAND_INHEADERFILE));
        }
    }
    else if (command == COMMAND_OVERLOAD) {
        if (node != 0 && node->type() == Node::Function) {
            ((FunctionNode *) node)->setOverload(true);
        }
        else {
            doc.location().warning(tr("Ignored '\\%1'")
                                   .arg(COMMAND_OVERLOAD));
        }
    }
    else if (command == COMMAND_REIMP) {
        if (node != 0 && node->type() == Node::Function) {
            FunctionNode *func = (FunctionNode *) node;
            const FunctionNode *from = func->reimplementedFrom();
            if (from == 0) {
                doc.location().warning(
                    tr("Cannot find base function for '\\%1' in %2()")
                    .arg(COMMAND_REIMP).arg(node->name()),
                    tr("The function either doesn't exist in any base class "
                       "with the same signature or it exists but isn't virtual."));
            }
            /*
              Ideally, we would enable this check to warn whenever
              \reimp is used incorrectly, and only make the node
              internal if the function is a reimplementation of
              another function in a base class.
            */
            else if (from->access() == Node::Private
                     || from->parent()->access() == Node::Private) {
                doc.location().warning(tr("'\\%1' in %2() should be '\\internal' because its base function is private or internal")
                    .arg(COMMAND_REIMP).arg(node->name()));
            }

            func->setReimp(true);
        }
        else {
            doc.location().warning(tr("Ignored '\\%1' in %2")
                                   .arg(COMMAND_REIMP)
                                   .arg(node->name()));
        }
    }
    else if (command == COMMAND_RELATES) {
        InnerNode *pseudoParent;
        if (arg.startsWith("<") || arg.startsWith("\"")) {
            pseudoParent =
                static_cast<InnerNode *>(tre->findNode(QStringList(arg),
                                                       Node::Fake));
        }
        else {
            QStringList newPath = arg.split("::");
            pseudoParent =
                static_cast<InnerNode*>(tre->findNode(QStringList(newPath),
                                                      Node::Class));
            if (!pseudoParent)
                pseudoParent =
                    static_cast<InnerNode*>(tre->findNode(QStringList(newPath),
                                                          Node::Namespace));
        }
        if (!pseudoParent) {
            doc.location().warning(tr("Cannot find '%1' in '\\%2'")
                                   .arg(arg).arg(COMMAND_RELATES));
        }
        else {
            node->setRelates(pseudoParent);
        }
    }
    else if (command == COMMAND_CONTENTSPAGE) {
        setLink(node, Node::ContentsLink, arg);
    }
    else if (command == COMMAND_NEXTPAGE) {
        setLink(node, Node::NextLink, arg);
    }
    else if (command == COMMAND_PREVIOUSPAGE) {
        setLink(node, Node::PreviousLink, arg);
    }
    else if (command == COMMAND_INDEXPAGE) {
        setLink(node, Node::IndexLink, arg);
    }
    else if (command == COMMAND_STARTPAGE) {
        setLink(node, Node::StartLink, arg);
    }
#ifdef QDOC_QML
    else if (command == COMMAND_QMLINHERITS) {
        setLink(node, Node::InheritsLink, arg);
        if (node->subType() == Node::QmlClass) {
            QmlClassNode::addInheritedBy(arg,node);
        }
   }
    else if (command == COMMAND_QMLDEFAULT) {
        QmlPropGroupNode* qpgn = static_cast<QmlPropGroupNode*>(node);
        qpgn->setDefault();
    }
#endif
    else {
        processCommonMetaCommand(doc.location(),command,arg,node,tre);
    }
}

/*!
  The topic command has been processed resulting in the \a doc
  and \a node passed in here. Process the other meta commands,
  which are found in \a doc, in the context of the topic \a node.
 */
void CppCodeParser::processOtherMetaCommands(const Doc& doc, Node *node)
{
    const QSet<QString> metaCommands = doc.metaCommandsUsed();
    QSet<QString>::ConstIterator cmd = metaCommands.begin();
    while (cmd != metaCommands.end()) {
        QStringList args = doc.metaCommandArgs(*cmd);
        QStringList::ConstIterator arg = args.begin();
        while (arg != args.end()) {
            processOtherMetaCommand(doc, *cmd, *arg, node);
            ++arg;
        }
        ++cmd;
    }
}

/*!
  Resets the C++ code parser to its default initialized state.
 */
void CppCodeParser::reset(Tree *tree)
{
    tre = tree;
    tokenizer = 0;
    tok = 0;
    access = Node::Public;
    metaness = FunctionNode::Plain;
    lastPath.clear();
    moduleName = "";
}

/*!
  Get the next token from the file being parsed and store it
  in the token variable.
 */
void CppCodeParser::readToken()
{
    tok = tokenizer->getToken();
}

/*!
  Return the current location in the file being parsed,
  i.e. the file name, line number, and column number.
 */
const Location& CppCodeParser::location()
{
    return tokenizer->location();
}

/*!
  Return the previous string read from the file being parsed.
 */
QString CppCodeParser::previousLexeme()
{
    return tokenizer->previousLexeme();
}

/*!
  Return the current string string from the file being parsed.
 */
QString CppCodeParser::lexeme()
{
    return tokenizer->lexeme();
}

bool CppCodeParser::match(int target)
{
    if (tok == target) {
        readToken();
        return true;
    }
    else
        return false;
}

/*!
  Skip to \a target. If \a target is found before the end
  of input, return true. Otherwise return false.
 */
bool CppCodeParser::skipTo(int target)
{
    while ((tok != Tok_Eoi) && (tok != target))
        readToken();
    return (tok == target ? true : false);
}

/*!
  If the current token is one of the keyword thingees that
  are used in Qt, skip over it to the next token and return
  true. Otherwise just return false without reading the
  next token.
 */
bool CppCodeParser::matchCompat()
{
    switch (tok) {
    case Tok_QT_COMPAT:
    case Tok_QT_COMPAT_CONSTRUCTOR:
    case Tok_QT_DEPRECATED:
    case Tok_QT_MOC_COMPAT:
    case Tok_QT3_SUPPORT:
    case Tok_QT3_SUPPORT_CONSTRUCTOR:
    case Tok_QT3_MOC_SUPPORT:
        readToken();
        return true;
    default:
        return false;
    }
}

bool CppCodeParser::matchTemplateAngles(CodeChunk *dataType)
{
    bool matches = (tok == Tok_LeftAngle);
    if (matches) {
        int leftAngleDepth = 0;
        int parenAndBraceDepth = 0;
        do {
            if (tok == Tok_LeftAngle) {
                leftAngleDepth++;
            }
            else if (tok == Tok_RightAngle) {
                leftAngleDepth--;
            }
            else if (tok == Tok_LeftParen || tok == Tok_LeftBrace) {
                ++parenAndBraceDepth;
            }
            else if (tok == Tok_RightParen || tok == Tok_RightBrace) {
                if (--parenAndBraceDepth < 0)
                    return false;
            }

            if (dataType != 0)
                dataType->append(lexeme());
            readToken();
        } while (leftAngleDepth > 0 && tok != Tok_Eoi);
    }
    return matches;
}

bool CppCodeParser::matchTemplateHeader()
{
    readToken();
    return matchTemplateAngles();
}

bool CppCodeParser::matchDataType(CodeChunk *dataType, QString *var)
{
    /*
      This code is really hard to follow... sorry. The loop is there to match
      Alpha::Beta::Gamma::...::Omega.
    */
    for (;;) {
        bool virgin = true;

        if (tok != Tok_Ident) {
            /*
              There is special processing for 'Foo::operator int()'
              and such elsewhere. This is the only case where we
              return something with a trailing gulbrandsen ('Foo::').
            */
            if (tok == Tok_operator)
                return true;

            /*
              People may write 'const unsigned short' or
              'short unsigned const' or any other permutation.
            */
            while (match(Tok_const) || match(Tok_volatile))
                dataType->append(previousLexeme());
            while (match(Tok_signed) || match(Tok_unsigned) ||
                    match(Tok_short) || match(Tok_long) || match(Tok_int64)) {
                dataType->append(previousLexeme());
                virgin = false;
            }
            while (match(Tok_const) || match(Tok_volatile))
                dataType->append(previousLexeme());

            if (match(Tok_Tilde))
                dataType->append(previousLexeme());
        }

        if (virgin) {
            if (match(Tok_Ident))
                dataType->append(previousLexeme());
            else if (match(Tok_void) || match(Tok_int) || match(Tok_char) ||
                      match(Tok_double) || match(Tok_Ellipsis))
                dataType->append(previousLexeme());
            else
                return false;
        }
        else if (match(Tok_int) || match(Tok_char) || match(Tok_double)) {
            dataType->append(previousLexeme());
        }

        matchTemplateAngles(dataType);

        while (match(Tok_const) || match(Tok_volatile))
            dataType->append(previousLexeme());

        if (match(Tok_Gulbrandsen))
            dataType->append(previousLexeme());
        else
            break;
    }

    while (match(Tok_Ampersand) || match(Tok_Aster) || match(Tok_const) ||
            match(Tok_Caret))
        dataType->append(previousLexeme());

    if (match(Tok_LeftParenAster)) {
        /*
          A function pointer. This would be rather hard to handle without a
          tokenizer hack, because a type can be followed with a left parenthesis
          in some cases (e.g., 'operator int()'). The tokenizer recognizes '(*'
          as a single token.
        */
        dataType->append(previousLexeme());
        dataType->appendHotspot();
        if (var != 0 && match(Tok_Ident))
            *var = previousLexeme();
        if (!match(Tok_RightParen) || tok != Tok_LeftParen)
            return false;
        dataType->append(previousLexeme());

        int parenDepth0 = tokenizer->parenDepth();
        while (tokenizer->parenDepth() >= parenDepth0 && tok != Tok_Eoi) {
            dataType->append(lexeme());
            readToken();
        }
        if (match(Tok_RightParen))
            dataType->append(previousLexeme());
    }
    else {
        /*
          The common case: Look for an optional identifier, then for
          some array brackets.
        */
        dataType->appendHotspot();

        if (var != 0) {
            if (match(Tok_Ident)) {
                *var = previousLexeme();
            }
            else if (match(Tok_Comment)) {
                /*
                  A neat hack: Commented-out parameter names are
                  recognized by qdoc. It's impossible to illustrate
                  here inside a C-style comment, because it requires
                  an asterslash. It's also impossible to illustrate
                  inside a C++-style comment, because the explanation
                  does not fit on one line.
                */
                if (varComment.exactMatch(previousLexeme()))
                    *var = varComment.cap(1);
            }
        }

        if (tok == Tok_LeftBracket) {
            int bracketDepth0 = tokenizer->bracketDepth();
            while ((tokenizer->bracketDepth() >= bracketDepth0 &&
                     tok != Tok_Eoi) ||
                    tok == Tok_RightBracket) {
                dataType->append(lexeme());
                readToken();
            }
        }
    }
    return true;
}

bool CppCodeParser::matchParameter(FunctionNode *func)
{
    CodeChunk dataType;
    QString name;
    CodeChunk defaultValue;

    if (!matchDataType(&dataType, &name))
        return false;
    match(Tok_Comment);
    if (match(Tok_Equal)) {
        int parenDepth0 = tokenizer->parenDepth();

        while (tokenizer->parenDepth() >= parenDepth0 &&
                (tok != Tok_Comma ||
                 tokenizer->parenDepth() > parenDepth0) &&
                tok != Tok_Eoi) {
            defaultValue.append(lexeme());
            readToken();
        }
    }
    func->addParameter(Parameter(dataType.toString(),
                                 "",
                                 name,
                                 defaultValue.toString())); // ###
    return true;
}

bool CppCodeParser::matchFunctionDecl(InnerNode *parent,
                                      QStringList *parentPathPtr,
                                      FunctionNode **funcPtr,
                                      const QString &templateStuff,
                                      Node::Type type,
                                      bool attached)
{
    CodeChunk returnType;
    QStringList parentPath;
    QString name;

    bool compat = false;

    if (match(Tok_friend))
        return false;
    match(Tok_explicit);
    if (matchCompat())
        compat = true;
    bool sta = false;
    if (match(Tok_static)) {
        sta = true;
        if (matchCompat())
            compat = true;
    }
    FunctionNode::Virtualness vir = FunctionNode::NonVirtual;
    if (match(Tok_virtual)) {
        vir = FunctionNode::ImpureVirtual;
        if (matchCompat())
            compat = true;
    }

    if (!matchDataType(&returnType)) {
        if (tokenizer->parsingFnOrMacro()
                && (match(Tok_Q_DECLARE_FLAGS) ||
                    match(Tok_Q_PROPERTY) ||
                    match(Tok_Q_PRIVATE_PROPERTY)))
            returnType = CodeChunk(previousLexeme());
        else {
            return false;
        }
    }

    if (returnType.toString() == "QBool")
        returnType = CodeChunk("bool");

    if (matchCompat())
        compat = true;

    if (tok == Tok_operator &&
         (returnType.toString().isEmpty() ||
          returnType.toString().endsWith("::"))) {
        // 'QString::operator const char *()'
        parentPath = returnType.toString().split(sep);
        parentPath.removeAll(QString());
        returnType = CodeChunk();
        readToken();

        CodeChunk restOfName;
        if (tok != Tok_Tilde && matchDataType(&restOfName)) {
            name = "operator " + restOfName.toString();
        }
        else {
            name = previousLexeme() + lexeme();
            readToken();
            while (tok != Tok_LeftParen && tok != Tok_Eoi) {
                name += lexeme();
                readToken();
            }
        }
        if (tok != Tok_LeftParen) {
            return false;
        }
    }
    else if (tok == Tok_LeftParen) {
        // constructor or destructor
        parentPath = returnType.toString().split(sep);
        if (!parentPath.isEmpty()) {
            name = parentPath.last();
            parentPath.erase(parentPath.end() - 1);
        }
        returnType = CodeChunk();
    }
    else {
        while (match(Tok_Ident)) {
            name = previousLexeme();
            matchTemplateAngles();

            if (match(Tok_Gulbrandsen))
                parentPath.append(name);
            else
                break;
        }

        if (tok == Tok_operator) {
            name = lexeme();
            readToken();
            while (tok != Tok_Eoi) {
                name += lexeme();
                readToken();
                if (tok == Tok_LeftParen)
                    break;
            }
        }
        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 (compat)
                var->setStatus(Node::Compat);
            var->setStatic(sta);
            return false;
        }
        if (tok != Tok_LeftParen) {
            return false;
        }
    }
    readToken();

    FunctionNode *func = new FunctionNode(type, parent, name, attached);
    func->setAccess(access);
    func->setLocation(location());
    func->setReturnType(returnType.toString());
    func->setParentPath(parentPath);
    func->setTemplateStuff(templateStuff);
    if (compat)
        func->setStatus(Node::Compat);

    func->setMetaness(metaness);
    if (parent) {
        if (name == parent->name()) {
            func->setMetaness(FunctionNode::Ctor);
        } else if (name.startsWith("~"))  {
            func->setMetaness(FunctionNode::Dtor);
        }
    }
    func->setStatic(sta);

    if (tok != Tok_RightParen) {
        do {
            if (!matchParameter(func)) {
                return false;
            }
        } while (match(Tok_Comma));
    }
    if (!match(Tok_RightParen)) {
        return false;
    }

    func->setConst(match(Tok_const));

    if (match(Tok_Equal) && match(Tok_Number))
        vir = FunctionNode::PureVirtual;
    func->setVirtualness(vir);

    if (match(Tok_Colon)) {
        while (tok != Tok_LeftBrace && tok != Tok_Eoi)
            readToken();
    }

    if (!match(Tok_Semicolon) && tok != Tok_Eoi) {
        int braceDepth0 = tokenizer->braceDepth();

        if (!match(Tok_LeftBrace)) {
            return false;
        }
        while (tokenizer->braceDepth() >= braceDepth0 && tok != Tok_Eoi)
            readToken();
        match(Tok_RightBrace);
    }
    if (parentPathPtr != 0)
        *parentPathPtr = parentPath;
    if (funcPtr != 0)
        *funcPtr = func;
    return true;
}

bool CppCodeParser::matchBaseSpecifier(ClassNode *classe, bool isClass)
{
    Node::Access access;

    switch (tok) {
    case Tok_public:
        access = Node::Public;
        readToken();
        break;
    case Tok_protected:
        access = Node::Protected;
        readToken();
        break;
    case Tok_private:
        access = Node::Private;
        readToken();
        break;
    default:
        access = isClass ? Node::Private : Node::Public;
    }

    if (tok == Tok_virtual)
        readToken();

    CodeChunk baseClass;
    if (!matchDataType(&baseClass))
        return false;

    tre->addBaseClass(classe,
                      access,
                      baseClass.toPath(),
                      baseClass.toString(),
                      classe->parent());
    return true;
}

bool CppCodeParser::matchBaseList(ClassNode *classe, bool isClass)
{
    for (;;) {
        if (!matchBaseSpecifier(classe, isClass))
            return false;
        if (tok == Tok_LeftBrace)
            return true;
        if (!match(Tok_Comma))
            return false;
    }
}

/*!
  Parse a C++ class, union, or struct declarion.
 */
bool CppCodeParser::matchClassDecl(InnerNode *parent,
                                   const QString &templateStuff)
{
    bool isClass = (tok == Tok_class);
    readToken();

    bool compat = matchCompat();

    if (tok != Tok_Ident)
        return false;
    while (tok == Tok_Ident)
        readToken();
    if (tok != Tok_Colon && tok != Tok_LeftBrace)
        return false;

    /*
      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());
    classe->setAccess(access);
    classe->setLocation(location());
    if (compat)
        classe->setStatus(Node::Compat);
    if (!moduleName.isEmpty())
        classe->setModuleName(moduleName);
    classe->setTemplateStuff(templateStuff);

    if (match(Tok_Colon) && !matchBaseList(classe, isClass))
        return false;
    if (!match(Tok_LeftBrace))
        return false;

    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;
    metaness = outerMetaness;
    return matches;
}

bool CppCodeParser::matchNamespaceDecl(InnerNode *parent)
{
    readToken(); // skip 'namespace'
    if (tok != Tok_Ident)
        return false;
    while (tok == Tok_Ident)
        readToken();
    if (tok != Tok_LeftBrace)
        return false;

    /*
        So far, so good. We have 'namespace Foo {'.
    */
    QString namespaceName = previousLexeme();
    NamespaceNode *namespasse = 0;
    if (parent) {
        namespasse = static_cast<NamespaceNode*>(parent->findNode(namespaceName, Node::Namespace));
    }
    if (!namespasse) {
        namespasse = new NamespaceNode(parent, namespaceName);
        namespasse->setAccess(access);
        namespasse->setLocation(location());
    }

    readToken(); // skip '{'
    bool matched = matchDeclList(namespasse);

    return matched && match(Tok_RightBrace);
}

bool CppCodeParser::matchUsingDecl()
{
    readToken(); // skip 'using'

    // 'namespace'
    if (tok != Tok_namespace)
        return false;

    readToken();
    // identifier
    if (tok != Tok_Ident)
        return false;

    QString name;
    while (tok == Tok_Ident) {
        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;'.
    */
    usedNamespaces.insert(name);
    return true;
}

bool CppCodeParser::matchEnumItem(InnerNode *parent, EnumNode *enume)
{
    if (!match(Tok_Ident))
        return false;

    QString name = previousLexeme();
    CodeChunk val;

    if (match(Tok_Equal)) {
        while (tok != Tok_Comma && tok != Tok_RightBrace &&
                tok != Tok_Eoi) {
            val.append(lexeme());
            readToken();
        }
    }

    if (enume) {
        QString strVal = val.toString();
        if (strVal.isEmpty()) {
            if (enume->items().isEmpty()) {
                strVal = "0";
            }
            else {
                QString last = enume->items().last().value();
                bool ok;
                int n = last.toInt(&ok);
                if (ok) {
                    if (last.startsWith("0") && last.size() > 1) {
                        if (last.startsWith("0x") || last.startsWith("0X"))
                            strVal = last.left(2) + QString::number(n + 1, 16);
                        else
                            strVal = "0" + QString::number(n + 1, 8);
                    }
                    else
                        strVal = QString::number(n + 1);
                }
            }
        }

        enume->addItem(EnumItem(name, strVal));
    }
    else {
        VariableNode *var = new VariableNode(parent, name);
        var->setAccess(access);
        var->setLocation(location());
        var->setLeftType("const int");
        var->setStatic(true);
    }
    return true;
}

bool CppCodeParser::matchEnumDecl(InnerNode *parent)
{
    QString name;

    if (!match(Tok_enum))
        return false;
    if (match(Tok_Ident))
        name = previousLexeme();
    if (tok != Tok_LeftBrace)
        return false;

    EnumNode *enume = 0;

    if (!name.isEmpty()) {
        enume = new EnumNode(parent, name);
        enume->setAccess(access);
        enume->setLocation(location());
    }

    readToken();

    if (!matchEnumItem(parent, enume))
        return false;

    while (match(Tok_Comma)) {
        if (!matchEnumItem(parent, enume))
            return false;
    }
    return match(Tok_RightBrace) && match(Tok_Semicolon);
}

bool CppCodeParser::matchTypedefDecl(InnerNode *parent)
{
    CodeChunk dataType;
    QString name;

    if (!match(Tok_typedef))
        return false;
    if (!matchDataType(&dataType, &name))
        return false;
    if (!match(Tok_Semicolon))
        return false;

    if (parent && !parent->findNode(name, Node::Typedef)) {
        TypedefNode *typedeffe = new TypedefNode(parent, name);
        typedeffe->setAccess(access);
        typedeffe->setLocation(location());
    }
    return true;
}

bool CppCodeParser::matchProperty(InnerNode *parent)
{
    int expected_tok = Tok_LeftParen;
    if (match(Tok_Q_PRIVATE_PROPERTY)) {
        expected_tok = Tok_Comma;
        if (!skipTo(Tok_Comma))
            return false;
    }
    else if (!match(Tok_Q_PROPERTY) &&
             !match(Tok_Q_OVERRIDE) &&
             !match(Tok_QDOC_PROPERTY)) {
        return false;
    }

    if (!match(expected_tok))
        return false;

    QString name;
    CodeChunk dataType;
    if (!matchDataType(&dataType, &name))
        return false;

    PropertyNode *property = new PropertyNode(parent, name);
    property->setAccess(Node::Public);
    property->setLocation(location());
    property->setDataType(dataType.toString());

    while (tok != Tok_RightParen && tok != Tok_Eoi) {
        if (!match(Tok_Ident))
            return false;
        QString key = previousLexeme();
        QString value;

        if (match(Tok_Ident) || match(Tok_Number)) {
            value = previousLexeme();
        }
        else if (match(Tok_LeftParen)) {
            int depth = 1;
            while (tok != Tok_Eoi) {
                if (tok == Tok_LeftParen) {
                    readToken();
                    ++depth;
                } else if (tok == Tok_RightParen) {
                    readToken();
                    if (--depth == 0)
                        break;
                } else {
                    readToken();
                }
            }
            value = "?";
        }

        if (key == "READ")
            tre->addPropertyFunction(property, value, PropertyNode::Getter);
        else if (key == "WRITE") {
            tre->addPropertyFunction(property, value, PropertyNode::Setter);
            property->setWritable(true);
        }
        else if (key == "STORED")
            property->setStored(value.toLower() == "true");
        else if (key == "DESIGNABLE") {
            QString v = value.toLower();
            if (v == "true")
                property->setDesignable(true);
            else if (v == "false")
                property->setDesignable(false);
            else {
                property->setDesignable(false);
                property->setRuntimeDesFunc(value);
            }
        }
        else if (key == "RESET")
            tre->addPropertyFunction(property, value, PropertyNode::Resetter);
        else if (key == "NOTIFY") {
            tre->addPropertyFunction(property, value, PropertyNode::Notifier);
        } else if (key == "REVISION") {
            int revision;
            bool ok;
            revision = value.toInt(&ok);
            if (ok)
                property->setRevision(revision);
            else
                parent->doc().location().warning(tr("Invalid revision number: %1").arg(value));
        } else if (key == "SCRIPTABLE") {
            QString v = value.toLower();
            if (v == "true")
                property->setScriptable(true);
            else if (v == "false")
                property->setScriptable(false);
            else {
                property->setScriptable(false);
                property->setRuntimeScrFunc(value);
            }
        }
        else if (key == "CONSTANT")
            property->setConstant();
        else if (key == "FINAL")
            property->setFinal();
    }
    match(Tok_RightParen);
    return true;
}

/*!
  Parse a C++ declaration.
 */
bool CppCodeParser::matchDeclList(InnerNode *parent)
{
    QString templateStuff;
    int braceDepth0 = tokenizer->braceDepth();
    if (tok == Tok_RightBrace) // prevents failure on empty body
        braceDepth0++;

    while (tokenizer->braceDepth() >= braceDepth0 && tok != Tok_Eoi) {
        switch (tok) {
        case Tok_Colon:
            readToken();
            break;
        case Tok_class:
        case Tok_struct:
        case Tok_union:
            matchClassDecl(parent, templateStuff);
            break;
        case Tok_namespace:
            matchNamespaceDecl(parent);
            break;
        case Tok_using:
            matchUsingDecl();
            break;
        case Tok_template:
            templateStuff = matchTemplateHeader();
            continue;
        case Tok_enum:
            matchEnumDecl(parent);
            break;
        case Tok_typedef:
            matchTypedefDecl(parent);
            break;
        case Tok_private:
            readToken();
            access = Node::Private;
            metaness = FunctionNode::Plain;
            break;
        case Tok_protected:
            readToken();
            access = Node::Protected;
            metaness = FunctionNode::Plain;
            break;
        case Tok_public:
            readToken();
            access = Node::Public;
            metaness = FunctionNode::Plain;
            break;
        case Tok_signals:
        case Tok_Q_SIGNALS:
            readToken();
            access = Node::Public;
            metaness = FunctionNode::Signal;
            break;
        case Tok_slots:
        case Tok_Q_SLOTS:
            readToken();
            metaness = FunctionNode::Slot;
            break;
        case Tok_Q_OBJECT:
            readToken();
            break;
        case Tok_Q_OVERRIDE:
        case Tok_Q_PROPERTY:
        case Tok_Q_PRIVATE_PROPERTY:
        case Tok_QDOC_PROPERTY:
            matchProperty(parent);
            break;
        case Tok_Q_DECLARE_SEQUENTIAL_ITERATOR:
            readToken();
            if (match(Tok_LeftParen) && match(Tok_Ident))
                sequentialIteratorClasses.insert(previousLexeme(),
                                                 location().fileName());
            match(Tok_RightParen);
            break;
        case Tok_Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR:
            readToken();
            if (match(Tok_LeftParen) && match(Tok_Ident))
                mutableSequentialIteratorClasses.insert(previousLexeme(),
                                                        location().fileName());
            match(Tok_RightParen);
            break;
        case Tok_Q_DECLARE_ASSOCIATIVE_ITERATOR:
            readToken();
            if (match(Tok_LeftParen) && match(Tok_Ident))
                associativeIteratorClasses.insert(previousLexeme(),
                                                  location().fileName());
            match(Tok_RightParen);
            break;
        case Tok_Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR:
            readToken();
            if (match(Tok_LeftParen) && match(Tok_Ident))
                mutableAssociativeIteratorClasses.insert(previousLexeme(),
                                                         location().fileName());
            match(Tok_RightParen);
            break;
        case Tok_Q_DECLARE_FLAGS:
            readToken();
            if (match(Tok_LeftParen) && match(Tok_Ident)) {
                QString flagsType = previousLexeme();
                if (match(Tok_Comma) && match(Tok_Ident)) {
                    QString enumType = previousLexeme();
                    TypedefNode *flagsNode = new TypedefNode(parent, flagsType);
                    flagsNode->setAccess(access);
                    flagsNode->setLocation(location());
                    EnumNode *enumNode =
                        static_cast<EnumNode*>(parent->findNode(enumType,
                                                                Node::Enum));
                    if (enumNode)
                        enumNode->setFlagsType(flagsNode);
                }
            }
            match(Tok_RightParen);
            break;
        case Tok_QT_MODULE:
            readToken();
            if (match(Tok_LeftParen) && match(Tok_Ident))
                moduleName = previousLexeme();
            if (!moduleName.startsWith("Qt"))
                moduleName.prepend("Qt");
            match(Tok_RightParen);
            break;
        default:
            if (!matchFunctionDecl(parent, 0, 0, templateStuff)) {
                while (tok != Tok_Eoi &&
                       (tokenizer->braceDepth() > braceDepth0 ||
                        (!match(Tok_Semicolon) &&
                         tok != Tok_public && tok != Tok_protected &&
                         tok != Tok_private)))
                    readToken();
            }
        }
        templateStuff.clear();
    }
    return true;
}

/*!
  This is called by parseSourceFile() to do the actual parsing
  and tree building.
 */
bool CppCodeParser::matchDocsAndStuff()
{
    QSet<QString> topicCommandsAllowed = topicCommands();
    QSet<QString> otherMetacommandsAllowed = otherMetaCommands();
    QSet<QString> metacommandsAllowed = topicCommandsAllowed +
        otherMetacommandsAllowed;

    while (tok != Tok_Eoi) {
        if (tok == Tok_Doc) {
            /*
              lexeme() returns an entire qdoc comment.
             */
            QString comment = lexeme();
            Location start_loc(location());
            readToken();

            Doc::trimCStyleComment(start_loc,comment);
            Location end_loc(location());

            /*
              Doc parses the comment.
             */
            Doc doc(start_loc,end_loc,comment,metacommandsAllowed);

            QString topic;
            QStringList args;

            QSet<QString> topicCommandsUsed = topicCommandsAllowed &
                doc.metaCommandsUsed();

            /*
              There should be one topic command in the set,
              or none. If the set is empty, then the comment
              should be a function description.
             */
            if (topicCommandsUsed.count() > 0) {
                topic = *topicCommandsUsed.begin();
                args = doc.metaCommandArgs(topic);
            }

            NodeList nodes;
            QList<Doc> docs;

            if (topic.isEmpty()) {
                QStringList parentPath;
                FunctionNode *clone;
                FunctionNode *func = 0;

                if (matchFunctionDecl(0, &parentPath, &clone)) {
                    foreach (const QString &usedNamespace, usedNamespaces) {
                        QStringList newPath = usedNamespace.split("::") + parentPath;
                        func = tre->findFunctionNode(newPath, clone);
                        if (func)
                            break;
                    }
                    if (func == 0)
                        func = tre->findFunctionNode(parentPath, clone);

                    if (func) {
                        func->borrowParameterNames(clone);
                        nodes.append(func);
                        docs.append(doc);
                    }
                    delete clone;
                }
                else {
                    doc.location().warning(
                       tr("Cannot tie this documentation to anything"),
                       tr("I found a /*! ... */ comment, but there was no "
                          "topic command (e.g., '\\%1', '\\%2') in the "
                          "comment and no function definition following "
                          "the comment.")
                       .arg(COMMAND_FN).arg(COMMAND_PAGE));
                }
            }
            else {
                /*
                  There is a topic command. Process it.
                 */
#ifdef QDOC_QML
                if ((topic == COMMAND_QMLPROPERTY) ||
                    (topic == COMMAND_QMLATTACHEDPROPERTY)) {
                    Doc nodeDoc = doc;
                    Node *node = processTopicCommandGroup(nodeDoc,topic,args);
                    if (node != 0) {
                        nodes.append(node);
                        docs.append(nodeDoc);
                    }
                }
                else {
                    QStringList::ConstIterator a = args.begin();
                    while (a != args.end()) {
                        Doc nodeDoc = doc;
                        Node *node = processTopicCommand(nodeDoc,topic,*a);
                        if (node != 0) {
                            nodes.append(node);
                            docs.append(nodeDoc);
                        }
                        ++a;
                    }
                }
#else
                QStringList::ConstIterator a = args.begin();
                while (a != args.end()) {
                    Doc nodeDoc = doc;
                    Node *node = processTopicCommand(nodeDoc, topic, *a);
                    if (node != 0) {
                        nodes.append(node);
                        docs.append(nodeDoc);
                    }
                    ++a;
                }
#endif
            }

            NodeList::Iterator n = nodes.begin();
            QList<Doc>::Iterator d = docs.begin();
            while (n != nodes.end()) {
                processOtherMetaCommands(*d, *n);
                (*n)->setDoc(*d);
                if ((*n)->isInnerNode() &&
                    ((InnerNode *)*n)->includes().isEmpty()) {
                    InnerNode *m = static_cast<InnerNode *>(*n);
                    while (m->parent() != tre->root())
                        m = m->parent();
                    if (m == *n)
                        ((InnerNode *)*n)->addInclude((*n)->name());
                    else
                        ((InnerNode *)*n)->setIncludes(m->includes());
                }
                ++d;
                ++n;
            }
        }
        else if (tok == Tok_using) {
            matchUsingDecl();
        }
        else {
            QStringList parentPath;
            FunctionNode *clone;
            FunctionNode *node = 0;

            if (matchFunctionDecl(0, &parentPath, &clone)) {
                /*
                  The location of the definition is more interesting
                  than that of the declaration. People equipped with
                  a sophisticated text editor can respond to warnings
                  concerning undocumented functions very quickly.

                  Signals are implemented in uninteresting files
                  generated by moc.
                */
                node = tre->findFunctionNode(parentPath, clone);
                if (node != 0 && node->metaness() != FunctionNode::Signal)
                    node->setLocation(clone->location());
                delete clone;
            }
            else {
                if (tok != Tok_Doc)
                    readToken();
            }
        }
    }
    return true;
}

bool CppCodeParser::makeFunctionNode(const QString& synopsis,
                                     QStringList *parentPathPtr,
                                     FunctionNode **funcPtr,
                                     InnerNode *root,
                                     Node::Type type,
                                     bool attached)
{
    Tokenizer *outerTokenizer = tokenizer;
    int outerTok = tok;

    Location loc;
    QByteArray latin1 = synopsis.toLatin1();
    Tokenizer stringTokenizer(loc, latin1);
    stringTokenizer.setParsingFnOrMacro(true);
    tokenizer = &stringTokenizer;
    readToken();

    bool ok = matchFunctionDecl(root, parentPathPtr, funcPtr, QString(), type, attached);
    // potential memory leak with funcPtr

    tokenizer = outerTokenizer;
    tok = outerTok;
    return ok;
}

/*!
  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.
 */
FunctionNode* CppCodeParser::makeFunctionNode(const Doc& doc,
                                              const QString& sig,
                                              InnerNode* parent,
                                              Node::Type type,
                                              bool attached,
                                              QString qdoctag)
{
    QStringList pp;
    FunctionNode* fn = 0;
    if (!makeFunctionNode(sig,&pp,&fn,parent,type,attached) &&
        !makeFunctionNode("void "+sig,&pp,&fn,parent,type,attached)) {
        doc.location().warning(tr("Invalid syntax in '\\%1'").arg(qdoctag));
    }
    if (fn)
        return fn;
    return 0;
}

void CppCodeParser::parseQiteratorDotH(const Location &location,
                                       const QString &filePath)
{
    QFile file(filePath);
    if (!file.open(QFile::ReadOnly))
        return;

    QString text = file.readAll();
    text.remove("\r");
    text.replace("\\\n", "");
    QStringList lines = text.split("\n");
    lines = lines.filter("Q_DECLARE");
    lines.replaceInStrings(QRegExp("#define Q[A-Z_]*\\(C\\)"), "");

    if (lines.size() == 4) {
        sequentialIteratorDefinition = lines[0];
        mutableSequentialIteratorDefinition = lines[1];
        associativeIteratorDefinition = lines[2];
        mutableAssociativeIteratorDefinition = lines[3];
    }
    else {
        location.warning(tr("The qiterator.h hack failed"));
    }
}

void CppCodeParser::instantiateIteratorMacro(const QString &container,
                                             const QString &includeFile,
                                             const QString &macroDef,
                                             Tree * /* tree */)
{
    QString resultingCode = macroDef;
    resultingCode.replace(QRegExp("\\bC\\b"), container);
    resultingCode.replace(QRegExp("\\s*##\\s*"), "");

    Location loc(includeFile);   // hack to get the include file for free
    QByteArray latin1 = resultingCode.toLatin1();
    Tokenizer stringTokenizer(loc, latin1);
    tokenizer = &stringTokenizer;
    readToken();
    matchDeclList(tre->root());
}

void CppCodeParser::createExampleFileNodes(FakeNode *fake)
{
    QString examplePath = fake->name();
    QString proFileName = examplePath + "/" + examplePath.split("/").last() + ".pro";
    QString userFriendlyFilePath;

    QString fullPath = Config::findFile(fake->doc().location(),
                                        exampleFiles,
                                        exampleDirs,
                                        proFileName,
                                        userFriendlyFilePath);

    if (fullPath.isEmpty()) {
        QString tmp = proFileName;
        proFileName = examplePath + "/" + "qbuild.pro";
        userFriendlyFilePath.clear();
        fullPath = Config::findFile(fake->doc().location(),
                                    exampleFiles,
                                    exampleDirs,
                                    proFileName,
                                    userFriendlyFilePath);
        if (fullPath.isEmpty()) {
            proFileName = examplePath + "/" + examplePath.split("/").last() + ".qmlproject";
            userFriendlyFilePath.clear();
            fullPath = Config::findFile(fake->doc().location(),
                                        exampleFiles,
                                        exampleDirs,
                                        proFileName,
                                        userFriendlyFilePath);
            if (fullPath.isEmpty()) {
                fake->doc().location().warning(
                    tr("Cannot find file '%1' or '%2'").arg(tmp).arg(proFileName));
                return;
            }
        }
    }

    int sizeOfBoringPartOfName = fullPath.size() - proFileName.size();
    fullPath.truncate(fullPath.lastIndexOf('/'));

    QStringList exampleFiles = Config::getFilesHere(fullPath,exampleNameFilter);
    QString imagesPath = fullPath + "/images";
    QStringList imageFiles = Config::getFilesHere(imagesPath,exampleImageFilter);

    if (!exampleFiles.isEmpty()) {
        // move main.cpp and to the end, if it exists
        QString mainCpp;
        QMutableStringListIterator i(exampleFiles);
        i.toBack();
        while (i.hasPrevious()) {
            QString fileName = i.previous();
            if (fileName.endsWith("/main.cpp")) {
                mainCpp = fileName;
                i.remove();
            }
            else if (fileName.contains("/qrc_") || fileName.contains("/moc_")
                || fileName.contains("/ui_"))
                i.remove();
        }
        if (!mainCpp.isEmpty())
            exampleFiles.append(mainCpp);

        // add any qmake Qt resource files and qmake project files
        exampleFiles += Config::getFilesHere(fullPath, "*.qrc *.pro qmldir");
    }

    foreach (const QString &exampleFile, exampleFiles)
        (void) new FakeNode(fake,
                            exampleFile.mid(sizeOfBoringPartOfName),
                            Node::File);
    foreach (const QString &imageFile, imageFiles) {
        new FakeNode(fake,
                     imageFile.mid(sizeOfBoringPartOfName),
                     Node::Image);
    }
}

QT_END_NAMESPACE
