add array information to symbol database

This commit is contained in:
Robert Reif 2011-06-22 22:41:11 -04:00
parent dac826d0ac
commit 0c46f44e3d
2 changed files with 91 additions and 8 deletions

View File

@ -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;

View File

@ -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++: