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++) for (size_t j = 0; j < _variableList[i]->dimensions().size(); j++)
{ {
// check for a single token dimension that is a variable // 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()) _variableList[i]->dimensions()[j].start->varId())
{ {
Dimension &dimension = const_cast<Dimension &>(_variableList[i]->dimensions()[j]); 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.name += tok2->str();
base.scope = 0; base.scope = NULL;
// add unhandled templates // add unhandled templates
if (tok2->next() && tok2->next()->str() == "<") 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() == "[") while (dim && dim->next() && dim->str() == "[")
{ {
Dimension dimension; Dimension dimension;
dimension.num = 0; // check for empty array dimension []
dimension.start = dim->next(); if (dim->next()->str() != "]")
dimension.end = dim->link()->previous(); {
if (dimension.start == dimension.end && dimension.start->isNumber()) dimension.start = dim->next();
dimension.num = MathLib::toLongNumber(dimension.start->str()); dimension.end = dim->link()->previous();
if (dimension.start == dimension.end && dimension.start->isNumber())
dimension.num = MathLib::toLongNumber(dimension.start->str());
}
dimensions.push_back(dimension); dimensions.push_back(dimension);
dim = dim->link()->next(); dim = dim->link()->next();
isArray = true; isArray = true;
@ -1388,6 +1392,11 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Function
else if (tok->str() == "[") else if (tok->str() == "[")
{ {
isArrayVar = symbolDatabase->arrayDimensions(dimensions, tok); isArrayVar = symbolDatabase->arrayDimensions(dimensions, tok);
// skip array dimension(s)
tok = tok->link();
while (tok->next()->str() == "[")
tok = tok->next()->link();
} }
else if (tok->str() == "<") else if (tok->str() == "<")
{ {

View File

@ -46,6 +46,8 @@ enum AccessControl { Public, Protected, Private, Global, Namespace, Argument, Lo
*/ */
struct Dimension struct Dimension
{ {
Dimension() : start(NULL), end(NULL), num(0) { }
const Token *start; // size start token const Token *start; // size start token
const Token *end; // size end token const Token *end; // size end token
MathLib::bigint num; // dimension length when size is a number, 0 if not known 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(hasGlobalVariables3);
TEST_CASE(functionArgs1); TEST_CASE(functionArgs1);
TEST_CASE(functionArgs2);
TEST_CASE(symboldatabase1); TEST_CASE(symboldatabase1);
TEST_CASE(symboldatabase2); TEST_CASE(symboldatabase2);
@ -658,6 +659,16 @@ private:
ASSERT_EQUALS("", errout.str()); 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() void symboldatabase1()
{ {
check("namespace foo {\n" check("namespace foo {\n"