void CheckPostfixOperator::postfixOperator()
{
    if (!_settings->isEnabled("performance"))
        return;

    const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();

    const std::size_t functions = symbolDatabase->functionScopes.size();
    for (std::size_t i = 0; i < functions; ++i) {
        const Scope * scope = symbolDatabase->functionScopes[i];
        for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
            const Variable *var = tok->variable();
            if (!var || !Token::Match(tok, "%var% ++|--"))
                continue;

            const Token* parent = tok->next()->astParent();
            if (!parent || parent->str() == ";" || (parent->str() == "," && (!parent->astParent() || parent->astParent()->str() != "("))) {
                if (var->isPointer() || var->isArray())
                    continue;

                if (Token::Match(var->nameToken()->previous(), "iterator|const_iterator|reverse_iterator|const_reverse_iterator")) {
                    // the variable is an iterator
                    postfixOperatorError(tok);
                } else if (var->type()) {
                    // the variable is an instance of class
                    postfixOperatorError(tok);
                }
            }
        }
    }
}
void CheckPostfixOperator::postfixOperator()
{
    if (!_settings->isEnabled("performance"))
        return;

    const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();

    const std::size_t functions = symbolDatabase->functionScopes.size();
    for (std::size_t i = 0; i < functions; ++i) {
        const Scope * scope = symbolDatabase->functionScopes[i];
        for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
            bool result = false;
            const Variable *var = tok->variable();
            if (var && Token::Match(tok, "%var% ++|--")) {
                if (Token::Match(tok->previous(), ";|{|}") && Token::Match(tok->tokAt(2), ";|,|)")) {
                    result = true;
                } else if (tok->strAt(-1) == ",") {
                    for (const Token* tok2 = tok->tokAt(2); tok2 != 0 && tok2->str() != ")"; tok2 = tok2->next()) {
                        if (tok2->str() == ";") {
                            result = true;
                            break;
                        } else if (tok2->str() == "(")
                            tok2 = tok2->link();
                    }
                } else if (tok->strAt(-1) == ".") {
                    for (const Token* tok2 = tok->tokAt(-2); tok2 != 0; tok2 = tok2->previous()) {
                        if (Token::Match(tok2, ";|{|}")) {
                            result = true;
                            break;
                        } else if (Token::Match(tok2, ")|]|>") && tok2->link())
                            tok2 = tok2->link();
                        else if (tok2->isAssignmentOp() || Token::Match(tok2, "(|["))
                            break;
                    }
                }
            }

            if (result) {
                if (var->isPointer() || var->isArray())
                    continue;

                const Token *decltok = var->nameToken();

                if (Token::Match(decltok->previous(), "iterator|const_iterator|reverse_iterator|const_reverse_iterator")) {
                    // the variable is an iterator
                    postfixOperatorError(tok);
                } else if (var->type()) {
                    // the variable is an instance of class
                    postfixOperatorError(tok);
                }
            }
        }
    }
}
void CheckPostfixOperator::postfixOperator()
{
    if (!_settings->isEnabled("performance"))
        return;

    const Token *tok = _tokenizer->tokens();
    const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();

    // prevent crash if first token is ++ or --
    if (Token::Match(tok, "++|--"))
        tok = tok->next();

    for (; tok; tok = tok->next()) {
        bool result = false;
        if (Token::Match(tok, "++|--")) {
            if (Token::Match(tok->tokAt(-2), ";|{|}") && Token::Match(tok->next(), ";|)|,")) {
                result = true;
            } else if (tok->strAt(-2) == ",") {
                int i(1);
                while (tok->strAt(i) != ")" && tok->tokAt(i) != 0) {
                    if (tok->strAt(i) == ";") {
                        result = true;
                        break;
                    }
                    ++i;
                }
            } else if (tok->strAt(-2) == "<<" && tok->strAt(1) == "<<") {
                result = true;
            }
        }

        if (result && tok->previous()->varId()) {
            const Variable *var = symbolDatabase->getVariableFromVarId(tok->previous()->varId());
            if (!var || var->isPointer() || var->isArray() || var->isReference())
                continue;

            const Token *decltok = var->nameToken();

            if (decltok && Token::Match(decltok->previous(), "iterator|const_iterator|reverse_iterator|const_reverse_iterator")) {
                // the variable is an iterator
                postfixOperatorError(tok);
            } else if (var->type()) {
                // the variable is an instance of class
                postfixOperatorError(tok);
            }
        }
    }
}
void CheckPostfixOperator::postfixOperator()
{
    if (!_settings->_checkCodingStyle)
        return;

    const Token *tok = _tokenizer->tokens();

    // prevent crash if first token is ++ or --
    if (Token::Match(tok, "++|--"))
        tok = tok->next();

    for (; tok; tok = tok->next())
    {
        bool result = false;
        if (Token::Match(tok, "++|--"))
        {
            if (Token::Match(tok->previous()->previous(), ";|{|}") && Token::Match(tok->next(), ";|)|,"))
            {
                result = true;
            }
            else if (tok->strAt(-2) == ",")
            {
                int i(1);
                while (tok->strAt(i) != ")" && tok->tokAt(i) != 0)
                {
                    if (tok->strAt(i) == ";")
                    {
                        result = true;
                        break;
                    }
                    ++i;
                }
            }
            else if (tok->strAt(-2) == "<<" && tok->strAt(1) == "<<")
            {
                result = true;
            }
        }

        if (result && tok->previous()->varId())
        {
            const Token *decltok = Token::findmatch(_tokenizer->tokens(), "%varid%", tok->previous()->varId());
            if (decltok == NULL || !Token::Match(decltok->tokAt(-1), "%type%"))
                continue;

            if (Token::Match(decltok->previous(), "iterator|const_iterator|reverse_iterator|const_reverse_iterator"))
            {
                // the variable is an iterator
                postfixOperatorError(tok);
            }
            else
            {
                const std::string classDef = std::string("class ") + std::string(decltok->previous()->strAt(0));
                if (Token::findmatch(_tokenizer->tokens(), classDef.c_str()))
                {
                    // the variable is an instance of class
                    postfixOperatorError(tok);
                }
            }
        }
    }
}