Library: Initial handling of method calls

This commit is contained in:
Daniel Marjamäki 2015-08-10 09:41:06 +02:00
parent 5b287fc849
commit 3a1a34751f
3 changed files with 67 additions and 4 deletions

View File

@ -131,6 +131,24 @@ bool astIsFloat(const Token *tok, bool unknown)
return unknown; return unknown;
} }
std::string astCanonicalType(const Token *expr)
{
if (!expr)
return "";
if (expr->variable()) {
const Variable *var = expr->variable();
std::string ret;
for (const Token *type = var->typeStartToken(); Token::Match(type,"%name%|::") && type != var->nameToken(); type = type->next()) {
if (!Token::Match(type, "const|static"))
ret += type->str();
}
return ret;
}
// TODO: handle expressions
return "";
}
const Token * astIsVariableComparison(const Token *tok, const std::string &comp, const std::string &rhs, const Token **vartok) const Token * astIsVariableComparison(const Token *tok, const std::string &comp, const std::string &rhs, const Token **vartok)
{ {
if (!tok) if (!tok)

View File

@ -35,6 +35,17 @@ bool astIsIntegral(const Token *tok, bool unknown);
/** Is expression of floating point type? */ /** Is expression of floating point type? */
bool astIsFloat(const Token *tok, bool unknown); bool astIsFloat(const Token *tok, bool unknown);
/**
* Get canonical type of expression. const/static/etc are not included and neither *&.
* For example:
* Expression type Return
* std::string std::string
* int * int
* static const int int
* std::vector<T> std::vector
*/
std::string astCanonicalType(const Token *expr);
/** Is given syntax tree a variable comparison against value */ /** Is given syntax tree a variable comparison against value */
const Token * astIsVariableComparison(const Token *tok, const std::string &comp, const std::string &rhs, const Token **vartok=nullptr); const Token * astIsVariableComparison(const Token *tok, const std::string &comp, const std::string &rhs, const Token **vartok=nullptr);

View File

@ -23,6 +23,7 @@
#include "mathlib.h" #include "mathlib.h"
#include "token.h" #include "token.h"
#include "symboldatabase.h" #include "symboldatabase.h"
#include "astutils.h"
#include <string> #include <string>
#include <algorithm> #include <algorithm>
@ -626,8 +627,45 @@ bool Library::isargvalid(const Token *ftok, int argnr, const MathLib::bigint arg
return false; return false;
} }
static std::string functionName(const Token *ftok, bool *error)
{
if (!ftok) {
*error = true;
return "";
}
if (ftok->isName())
return ftok->str();
if (ftok->str() == "::") {
if (!ftok->astOperand2())
return functionName(ftok->astOperand1(), error);
return functionName(ftok->astOperand1(),error) + "::" + functionName(ftok->astOperand2(),error);
}
if (ftok->str() == "." && ftok->astOperand1()) {
const std::string type = astCanonicalType(ftok->astOperand1());
if (type.empty()) {
*error = true;
return "";
}
return type + "::" + functionName(ftok->astOperand2(),error);
}
*error = true;
return "";
}
static std::string functionName(const Token *ftok) static std::string functionName(const Token *ftok)
{ {
if (!Token::Match(ftok, "%name% ("))
return "";
// Lookup function name using AST..
if (ftok->astParent()) {
bool error = false;
std::string ret = functionName(ftok->next()->astOperand1(), &error);
return error ? std::string() : ret;
}
// Lookup function name without using AST..
if (Token::simpleMatch(ftok->previous(), ".")) if (Token::simpleMatch(ftok->previous(), "."))
return ""; return "";
if (!Token::Match(ftok->tokAt(-2), "%name% ::")) if (!Token::Match(ftok->tokAt(-2), "%name% ::"))
@ -715,10 +753,6 @@ const Library::Container* Library::detectContainer(const Token* typeStart) const
// returns true if ftok is not a library function // returns true if ftok is not a library function
bool Library::isNotLibraryFunction(const Token *ftok) const bool Library::isNotLibraryFunction(const Token *ftok) const
{ {
// methods are not library functions
// called from tokenizer, ast is not created properly yet
if (Token::simpleMatch(ftok->previous(),"."))
return true;
if (ftok->function() && ftok->function()->nestedIn && ftok->function()->nestedIn->type != Scope::eGlobal) if (ftok->function() && ftok->function()->nestedIn && ftok->function()->nestedIn->type != Scope::eGlobal)
return true; return true;