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 *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();
|
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
|
unsigned int Function::initializedArgCount() const
|
||||||
|
@ -1255,6 +1283,7 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Function
|
||||||
isConstVar = bool(tok->str() == "const");
|
isConstVar = bool(tok->str() == "const");
|
||||||
isArrayVar = false;
|
isArrayVar = false;
|
||||||
hasDefault = false;
|
hasDefault = false;
|
||||||
|
std::vector<Dimension> dimensions;
|
||||||
|
|
||||||
while (tok->str() != "," && tok->str() != ")" && tok->str() != "=")
|
while (tok->str() != "," && tok->str() != ")" && tok->str() != "=")
|
||||||
{
|
{
|
||||||
|
@ -1264,7 +1293,9 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Function
|
||||||
endTok = tok->previous();
|
endTok = tok->previous();
|
||||||
}
|
}
|
||||||
else if (tok->str() == "[")
|
else if (tok->str() == "[")
|
||||||
isArrayVar = true;
|
{
|
||||||
|
isArrayVar = symbolDatabase->arrayDimensions(dimensions, tok);
|
||||||
|
}
|
||||||
else if (tok->str() == "<")
|
else if (tok->str() == "<")
|
||||||
{
|
{
|
||||||
int level = 1;
|
int level = 1;
|
||||||
|
@ -1327,7 +1358,7 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Function
|
||||||
tok = tok->next();
|
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() == ")")
|
if (tok->str() == ")")
|
||||||
break;
|
break;
|
||||||
|
@ -1618,10 +1649,19 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isArray = false;
|
bool isArray = false;
|
||||||
|
std::vector<Dimension> dimensions;
|
||||||
|
|
||||||
if (tok && isVariableDeclaration(tok, vartok, typetok, isArray))
|
if (tok && isVariableDeclaration(tok, vartok, typetok, isArray))
|
||||||
{
|
{
|
||||||
isClass = (!typetok->isStandardType() && vartok->previous()->str() != "*");
|
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();
|
tok = vartok->next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1636,7 +1676,7 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess)
|
||||||
if (typetok)
|
if (typetok)
|
||||||
scope = check->findVariableType(this, 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;
|
return tok;
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
|
#include "mathlib.h"
|
||||||
|
|
||||||
class Tokenizer;
|
class Tokenizer;
|
||||||
class Settings;
|
class Settings;
|
||||||
|
@ -40,6 +41,16 @@ class SymbolDatabase;
|
||||||
*/
|
*/
|
||||||
enum AccessControl { Public, Protected, Private, Global, Namespace, Argument, Local };
|
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. */
|
/** @brief Information about a member variable. */
|
||||||
class Variable
|
class Variable
|
||||||
{
|
{
|
||||||
|
@ -78,7 +89,8 @@ public:
|
||||||
Variable(const Token *name_, const Token *start_, const Token *end_,
|
Variable(const Token *name_, const Token *start_, const Token *end_,
|
||||||
std::size_t index_, AccessControl access_, bool mutable_,
|
std::size_t index_, AccessControl access_, bool mutable_,
|
||||||
bool static_, bool const_, bool class_, const Scope *type_,
|
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_),
|
: _name(name_),
|
||||||
_start(start_),
|
_start(start_),
|
||||||
_end(end_),
|
_end(end_),
|
||||||
|
@ -94,6 +106,7 @@ public:
|
||||||
setFlag(fIsClass, class_);
|
setFlag(fIsClass, class_);
|
||||||
setFlag(fIsArray, array_);
|
setFlag(fIsArray, array_);
|
||||||
setFlag(fHasDefault, default_);
|
setFlag(fHasDefault, default_);
|
||||||
|
_dimensions = dimensions_;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -295,6 +308,24 @@ public:
|
||||||
return _scope;
|
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:
|
private:
|
||||||
/** @brief variable name token */
|
/** @brief variable name token */
|
||||||
const Token *_name;
|
const Token *_name;
|
||||||
|
@ -319,6 +350,9 @@ private:
|
||||||
|
|
||||||
/** @brief pointer to scope this variable is in */
|
/** @brief pointer to scope this variable is in */
|
||||||
const Scope *_scope;
|
const Scope *_scope;
|
||||||
|
|
||||||
|
/** @brief array dimensions */
|
||||||
|
std::vector<Dimension> _dimensions;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Function
|
class Function
|
||||||
|
@ -452,11 +486,12 @@ public:
|
||||||
void addVariable(const Token *token_, const Token *start_,
|
void addVariable(const Token *token_, const Token *start_,
|
||||||
const Token *end_, AccessControl access_, bool mutable_,
|
const Token *end_, AccessControl access_, bool mutable_,
|
||||||
bool static_, bool const_, bool class_, const Scope *type_,
|
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(),
|
varlist.push_back(Variable(token_, start_, end_, varlist.size(),
|
||||||
access_, mutable_, static_, const_, class_,
|
access_, mutable_, static_, const_, class_,
|
||||||
type_, scope_, array_, false));
|
type_, scope_, array_, false, dimensions_));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief initialize varlist */
|
/** @brief initialize varlist */
|
||||||
|
@ -536,6 +571,14 @@ public:
|
||||||
*/
|
*/
|
||||||
void debugMessage(const Token *tok, const std::string &msg) const;
|
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:
|
private:
|
||||||
|
|
||||||
// Needed by Borland C++:
|
// Needed by Borland C++:
|
||||||
|
|
Loading…
Reference in New Issue