add array information to symbol database
This commit is contained in:
parent
dac826d0ac
commit
0c46f44e3d
|
@ -118,7 +118,14 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
|||
|
||||
Scope *new_scope = &scopeList.back();
|
||||
|
||||
scope->addVariable(tok->next()->link()->next(), tok, tok, scope->access, false, false, false, true, new_scope, scope, tok->next()->link()->strAt(2) == "[");
|
||||
std::vector<Dimension> dimensions;
|
||||
|
||||
bool isArray = false;
|
||||
|
||||
if (tok->next()->link()->strAt(2) == "[")
|
||||
isArray = arrayDimensions(dimensions, tok->next()->link()->tokAt(2));
|
||||
|
||||
scope->addVariable(tok->next()->link()->next(), tok, tok, scope->access, false, false, false, true, new_scope, scope, isArray, dimensions);
|
||||
|
||||
const Token *tok2 = tok->next();
|
||||
|
||||
|
@ -1218,6 +1225,27 @@ void SymbolDatabase::debugMessage(const Token *tok, const std::string &msg) cons
|
|||
}
|
||||
}
|
||||
|
||||
bool SymbolDatabase::arrayDimensions(std::vector<Dimension> &dimensions, const Token *tok) const
|
||||
{
|
||||
bool isArray = false;
|
||||
|
||||
const Token *dim = tok;
|
||||
|
||||
while (dim->str() == "[" && dim->next() && dim->next()->str() != "]")
|
||||
{
|
||||
Dimension dimension;
|
||||
dimension.num = 0;
|
||||
dimension.start = dim->next();
|
||||
dimension.end = dim->link()->previous();
|
||||
if (dimension.start == dimension.end && dimension.start->isNumber())
|
||||
dimension.num = MathLib::toLongNumber(dimension.start->str());
|
||||
dimensions.push_back(dimension);
|
||||
dim = dim->link()->next();
|
||||
isArray = true;
|
||||
}
|
||||
return isArray;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
unsigned int Function::initializedArgCount() const
|
||||
|
@ -1255,6 +1283,7 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Function
|
|||
isConstVar = bool(tok->str() == "const");
|
||||
isArrayVar = false;
|
||||
hasDefault = false;
|
||||
std::vector<Dimension> dimensions;
|
||||
|
||||
while (tok->str() != "," && tok->str() != ")" && tok->str() != "=")
|
||||
{
|
||||
|
@ -1264,7 +1293,9 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Function
|
|||
endTok = tok->previous();
|
||||
}
|
||||
else if (tok->str() == "[")
|
||||
isArrayVar = true;
|
||||
{
|
||||
isArrayVar = symbolDatabase->arrayDimensions(dimensions, tok);
|
||||
}
|
||||
else if (tok->str() == "<")
|
||||
{
|
||||
int level = 1;
|
||||
|
@ -1327,7 +1358,7 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Function
|
|||
tok = tok->next();
|
||||
}
|
||||
|
||||
argumentList.push_back(Variable(nameTok, startTok, endTok, count++, Argument, false, false, isConstVar, isClassVar, argType, functionScope, isArrayVar, hasDefault));
|
||||
argumentList.push_back(Variable(nameTok, startTok, endTok, count++, Argument, false, false, isConstVar, isClassVar, argType, functionScope, isArrayVar, hasDefault, dimensions));
|
||||
|
||||
if (tok->str() == ")")
|
||||
break;
|
||||
|
@ -1618,10 +1649,19 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess)
|
|||
}
|
||||
|
||||
bool isArray = false;
|
||||
std::vector<Dimension> dimensions;
|
||||
|
||||
if (tok && isVariableDeclaration(tok, vartok, typetok, isArray))
|
||||
{
|
||||
isClass = (!typetok->isStandardType() && vartok->previous()->str() != "*");
|
||||
if (isArray)
|
||||
{
|
||||
isArray = check->arrayDimensions(dimensions, vartok->next());
|
||||
tok = vartok->next();
|
||||
while (tok && tok->str() == "[")
|
||||
tok = tok->link()->next();
|
||||
}
|
||||
else
|
||||
tok = vartok->next();
|
||||
}
|
||||
|
||||
|
@ -1636,7 +1676,7 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess)
|
|||
if (typetok)
|
||||
scope = check->findVariableType(this, typetok);
|
||||
|
||||
addVariable(vartok, typestart, vartok->previous(), varaccess, isMutable, isStatic, isConst, isClass, scope, this, isArray);
|
||||
addVariable(vartok, typestart, vartok->previous(), varaccess, isMutable, isStatic, isConst, isClass, scope, this, isArray, dimensions);
|
||||
}
|
||||
|
||||
return tok;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <set>
|
||||
|
||||
#include "token.h"
|
||||
#include "mathlib.h"
|
||||
|
||||
class Tokenizer;
|
||||
class Settings;
|
||||
|
@ -40,6 +41,16 @@ class SymbolDatabase;
|
|||
*/
|
||||
enum AccessControl { Public, Protected, Private, Global, Namespace, Argument, Local };
|
||||
|
||||
/**
|
||||
* @brief Array dimension information.
|
||||
*/
|
||||
struct Dimension
|
||||
{
|
||||
const Token *start; // size start token
|
||||
const Token *end; // size end token
|
||||
MathLib::bigint num; // dimension length when size is a number, 0 if not known
|
||||
};
|
||||
|
||||
/** @brief Information about a member variable. */
|
||||
class Variable
|
||||
{
|
||||
|
@ -78,7 +89,8 @@ public:
|
|||
Variable(const Token *name_, const Token *start_, const Token *end_,
|
||||
std::size_t index_, AccessControl access_, bool mutable_,
|
||||
bool static_, bool const_, bool class_, const Scope *type_,
|
||||
const Scope *scope_, bool array_, bool default_)
|
||||
const Scope *scope_, bool array_, bool default_,
|
||||
const std::vector<Dimension> &dimensions_)
|
||||
: _name(name_),
|
||||
_start(start_),
|
||||
_end(end_),
|
||||
|
@ -94,6 +106,7 @@ public:
|
|||
setFlag(fIsClass, class_);
|
||||
setFlag(fIsArray, array_);
|
||||
setFlag(fHasDefault, default_);
|
||||
_dimensions = dimensions_;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -295,6 +308,24 @@ public:
|
|||
return _scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array dimensions.
|
||||
* @return array dimensions vector
|
||||
*/
|
||||
const std::vector<Dimension> &dimensions() const
|
||||
{
|
||||
return _dimensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array dimension length.
|
||||
* @return length of dimension
|
||||
*/
|
||||
MathLib::bigint dimension(size_t index_) const
|
||||
{
|
||||
return _dimensions[index_].num;
|
||||
}
|
||||
|
||||
private:
|
||||
/** @brief variable name token */
|
||||
const Token *_name;
|
||||
|
@ -319,6 +350,9 @@ private:
|
|||
|
||||
/** @brief pointer to scope this variable is in */
|
||||
const Scope *_scope;
|
||||
|
||||
/** @brief array dimensions */
|
||||
std::vector<Dimension> _dimensions;
|
||||
};
|
||||
|
||||
class Function
|
||||
|
@ -452,11 +486,12 @@ public:
|
|||
void addVariable(const Token *token_, const Token *start_,
|
||||
const Token *end_, AccessControl access_, bool mutable_,
|
||||
bool static_, bool const_, bool class_, const Scope *type_,
|
||||
const Scope *scope_, bool array_)
|
||||
const Scope *scope_, bool array_,
|
||||
const std::vector<Dimension> &dimensions_)
|
||||
{
|
||||
varlist.push_back(Variable(token_, start_, end_, varlist.size(),
|
||||
access_, mutable_, static_, const_, class_,
|
||||
type_, scope_, array_, false));
|
||||
type_, scope_, array_, false, dimensions_));
|
||||
}
|
||||
|
||||
/** @brief initialize varlist */
|
||||
|
@ -536,6 +571,14 @@ public:
|
|||
*/
|
||||
void debugMessage(const Token *tok, const std::string &msg) const;
|
||||
|
||||
/**
|
||||
* @brief parse and save array dimension information
|
||||
* @param dimensions array dimensions vector
|
||||
* @param tokenizer tokenizer pointer
|
||||
* @return true if array, false if not
|
||||
*/
|
||||
bool arrayDimensions(std::vector<Dimension> &dimensions, const Token *tok) const;
|
||||
|
||||
private:
|
||||
|
||||
// Needed by Borland C++:
|
||||
|
|
Loading…
Reference in New Issue