really fix multi-dimensional arrays with undefined size

This commit is contained in:
Robert Reif 2011-08-28 13:32:42 -04:00
parent 787bc4c384
commit 7775934492
3 changed files with 29 additions and 7 deletions

View File

@ -813,7 +813,8 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
for (size_t j = 0; j < _variableList[i]->dimensions().size(); j++)
{
// check for a single token dimension that is a variable
if ((_variableList[i]->dimensions()[j].start == _variableList[i]->dimensions()[j].end) &&
if (_variableList[i]->dimensions()[j].start &&
(_variableList[i]->dimensions()[j].start == _variableList[i]->dimensions()[j].end) &&
_variableList[i]->dimensions()[j].start->varId())
{
Dimension &dimension = const_cast<Dimension &>(_variableList[i]->dimensions()[j]);
@ -1261,7 +1262,7 @@ const Token *SymbolDatabase::initBaseInfo(Scope *scope, const Token *tok)
}
base.name += tok2->str();
base.scope = 0;
base.scope = NULL;
// add unhandled templates
if (tok2->next() && tok2->next()->str() == "<")
@ -1327,11 +1328,14 @@ bool SymbolDatabase::arrayDimensions(std::vector<Dimension> &dimensions, const T
while (dim && dim->next() && dim->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());
// check for empty array dimension []
if (dim->next()->str() != "]")
{
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;
@ -1388,6 +1392,11 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Function
else if (tok->str() == "[")
{
isArrayVar = symbolDatabase->arrayDimensions(dimensions, tok);
// skip array dimension(s)
tok = tok->link();
while (tok->next()->str() == "[")
tok = tok->next()->link();
}
else if (tok->str() == "<")
{

View File

@ -46,6 +46,8 @@ enum AccessControl { Public, Protected, Private, Global, Namespace, Argument, Lo
*/
struct Dimension
{
Dimension() : start(NULL), end(NULL), num(0) { }
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

View File

@ -102,6 +102,7 @@ private:
TEST_CASE(hasGlobalVariables3);
TEST_CASE(functionArgs1);
TEST_CASE(functionArgs2);
TEST_CASE(symboldatabase1);
TEST_CASE(symboldatabase2);
@ -658,6 +659,16 @@ private:
ASSERT_EQUALS("", errout.str());
}
void functionArgs2()
{
GET_SYMBOL_DB("void f(int a[][4]) { }");
const Variable *a = db->getVariableFromVarId(1);
ASSERT_EQUALS("a", a->nameToken()->str());
ASSERT_EQUALS(2UL, a->dimensions().size());
ASSERT_EQUALS(0UL, a->dimension(0));
ASSERT_EQUALS(4UL, a->dimension(1));
}
void symboldatabase1()
{
check("namespace foo {\n"