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 *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,11 +1649,20 @@ 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() != "*");
tok = vartok->next(); if (isArray)
{
isArray = check->arrayDimensions(dimensions, vartok->next());
tok = vartok->next();
while (tok && tok->str() == "[")
tok = tok->link()->next();
}
else
tok = vartok->next();
} }
// If the vartok was set in the if-blocks above, create a entry for this variable.. // If the vartok was set in the if-blocks above, create a entry for this variable..
@ -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;

View File

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