add an array flag to symbol database Variable class

This commit is contained in:
Robert Reif 2011-02-27 10:21:14 -05:00
parent 0872f1291e
commit 962183f964
3 changed files with 76 additions and 31 deletions

View File

@ -1156,7 +1156,7 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s
bool isClassVar = startTok == endTok && !startTok->isStandardType();
argumentList.push_back(Variable(nameTok, startTok, endTok, count++, Argument, false, false, isConstVar, isClassVar, argType, scope));
argumentList.push_back(Variable(nameTok, startTok, endTok, count++, Argument, false, false, isConstVar, isClassVar, argType, scope, false));
if (tok->str() == ")")
break;
@ -1418,7 +1418,9 @@ void Scope::getVariableList()
tok = tok->next();
}
if (isVariableDeclaration(tok, vartok, typetok))
bool isArray = false;
if (isVariableDeclaration(tok, vartok, typetok, isArray))
{
isClass = (!typetok->isStandardType() && vartok->previous()->str() != "*");
tok = vartok->next();
@ -1450,7 +1452,7 @@ void Scope::getVariableList()
if (typetok)
scope = check->findVariableType(this, typetok);
addVariable(vartok, typestart, vartok->previous(), varaccess, isMutable, isStatic, isConst, isClass, scope, this);
addVariable(vartok, typestart, vartok->previous(), varaccess, isMutable, isStatic, isConst, isClass, scope, this, isArray);
}
}
}
@ -1483,7 +1485,7 @@ const Token* skipPointers(const Token* tok)
return ret;
}
bool Scope::isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const
bool Scope::isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok, bool &isArray) const
{
const Token* localTypeTok = skipScopeIdentifiers(tok);
const Token* localVarTok = NULL;
@ -1508,10 +1510,17 @@ bool Scope::isVariableDeclaration(const Token* tok, const Token*& vartok, const
localVarTok = skipPointers(localTypeTok->next());
}
if (isSimpleVariable(localVarTok) || isArrayVariable(localVarTok))
if (isSimpleVariable(localVarTok))
{
vartok = localVarTok;
typetok = localTypeTok;
isArray = false;
}
else if (isArrayVariable(localVarTok))
{
vartok = localVarTok;
typetok = localTypeTok;
isArray = true;
}
return NULL != vartok;

View File

@ -49,7 +49,8 @@ class Variable
fIsMutable = (1 << 0), /** @brief mutable variable */
fIsStatic = (1 << 1), /** @brief static variable */
fIsConst = (1 << 2), /** @brief const variable */
fIsClass = (1 << 3) /** @brief user defined type */
fIsClass = (1 << 3), /** @brief user defined type */
fIsArray = (1 << 4) /** @brief array variable */
};
/**
@ -76,7 +77,7 @@ 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_)
const Scope *scope_, bool array_)
: _name(name_),
_start(start_),
_end(end_),
@ -90,6 +91,7 @@ public:
setFlag(fIsStatic, static_);
setFlag(fIsConst, const_);
setFlag(fIsClass, class_);
setFlag(fIsArray, array_);
}
/**
@ -255,6 +257,15 @@ public:
return getFlag(fIsClass);
}
/**
* Is variable an array.
* @return true if array, false if not
*/
bool isArray() const
{
return getFlag(fIsArray);
}
/**
* Get Scope pointer of known type.
* @return pointer to type if known, NULL if not known
@ -417,11 +428,11 @@ 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_)
const Scope *scope_, bool array_)
{
varlist.push_back(Variable(token_, start_, end_, varlist.size(),
access_, mutable_, static_, const_, class_,
type_, scope_));
type_, scope_, array_));
}
/** @brief initialize varlist */
@ -447,9 +458,10 @@ private:
* @param tok pointer to token to check
* @param vartok populated with pointer to the variable token, if found
* @param typetok populated with pointer to the type token, if found
* @param isArray reference to variable to set if array is found
* @return true if tok points to a variable declaration, false otherwise
*/
bool isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const;
bool isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok, bool &isArray) const;
bool isSimpleVariable(const Token* tok) const;
bool isArrayVariable(const Token* tok) const;
bool findClosingBracket(const Token* tok, const Token*& close) const;

View File

@ -38,6 +38,7 @@ public:
,typetok(NULL)
,t(NULL)
,found(false)
,isArray(false)
{}
private:
@ -46,6 +47,7 @@ private:
const Token* typetok;
const Token* t;
bool found;
bool isArray;
void reset()
{
@ -53,6 +55,7 @@ private:
typetok = NULL;
t = NULL;
found = false;
isArray = false;
}
void run()
@ -102,208 +105,229 @@ private:
void test_isVariableDeclarationCanHandleNull()
{
reset();
bool result = si.isVariableDeclaration(NULL, vartok, typetok);
bool result = si.isVariableDeclaration(NULL, vartok, typetok, isArray);
ASSERT_EQUALS(false, result);
ASSERT(NULL == vartok);
ASSERT(NULL == typetok);
ASSERT(false == isArray);
}
void test_isVariableDeclarationIdentifiesSimpleDeclaration()
{
reset();
givenACodeSampleToTokenize simpleDeclaration("int x;");
bool result = si.isVariableDeclaration(simpleDeclaration.tokens(), vartok, typetok);
bool result = si.isVariableDeclaration(simpleDeclaration.tokens(), vartok, typetok, isArray);
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("x", vartok->str());
ASSERT_EQUALS("int", typetok->str());
ASSERT(false == isArray);
}
void test_isVariableDeclarationIdentifiesScopedDeclaration()
{
reset();
givenACodeSampleToTokenize ScopedDeclaration("::int x;");
bool result = si.isVariableDeclaration(ScopedDeclaration.tokens(), vartok, typetok);
bool result = si.isVariableDeclaration(ScopedDeclaration.tokens(), vartok, typetok, isArray);
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("x", vartok->str());
ASSERT_EQUALS("int", typetok->str());
ASSERT(false == isArray);
}
void test_isVariableDeclarationIdentifiesStdDeclaration()
{
reset();
givenACodeSampleToTokenize StdDeclaration("std::string x;");
bool result = si.isVariableDeclaration(StdDeclaration.tokens(), vartok, typetok);
bool result = si.isVariableDeclaration(StdDeclaration.tokens(), vartok, typetok, isArray);
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("x", vartok->str());
ASSERT_EQUALS("string", typetok->str());
ASSERT(false == isArray);
}
void test_isVariableDeclarationIdentifiesScopedStdDeclaration()
{
reset();
givenACodeSampleToTokenize StdDeclaration("::std::string x;");
bool result = si.isVariableDeclaration(StdDeclaration.tokens(), vartok, typetok);
bool result = si.isVariableDeclaration(StdDeclaration.tokens(), vartok, typetok, isArray);
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("x", vartok->str());
ASSERT_EQUALS("string", typetok->str());
ASSERT(false == isArray);
}
void test_isVariableDeclarationIdentifiesManyScopes()
{
reset();
givenACodeSampleToTokenize manyScopes("AA::BB::CC::DD::EE x;");
bool result = si.isVariableDeclaration(manyScopes.tokens(), vartok, typetok);
bool result = si.isVariableDeclaration(manyScopes.tokens(), vartok, typetok, isArray);
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("x", vartok->str());
ASSERT_EQUALS("EE", typetok->str());
ASSERT(false == isArray);
}
void test_isVariableDeclarationIdentifiesPointers()
{
reset();
givenACodeSampleToTokenize pointer("int* p;");
bool result = si.isVariableDeclaration(pointer.tokens(), vartok, typetok);
bool result = si.isVariableDeclaration(pointer.tokens(), vartok, typetok, isArray);
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("p", vartok->str());
ASSERT_EQUALS("int", typetok->str());
ASSERT(false == isArray);
}
void test_isVariableDeclarationDoesNotIdentifyConstness()
{
reset();
givenACodeSampleToTokenize constness("const int* cp;");
bool result = si.isVariableDeclaration(constness.tokens(), vartok, typetok);
bool result = si.isVariableDeclaration(constness.tokens(), vartok, typetok, isArray);
ASSERT_EQUALS(false, result);
ASSERT(NULL == vartok);
ASSERT(NULL == typetok);
ASSERT(false == isArray);
}
void test_isVariableDeclarationIdentifiesFirstOfManyVariables()
{
reset();
givenACodeSampleToTokenize multipleDeclaration("int first, second;");
bool result = si.isVariableDeclaration(multipleDeclaration.tokens(), vartok, typetok);
bool result = si.isVariableDeclaration(multipleDeclaration.tokens(), vartok, typetok, isArray);
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("first", vartok->str());
ASSERT_EQUALS("int", typetok->str());
ASSERT(false == isArray);
}
void test_isVariableDeclarationIdentifiesScopedPointerDeclaration()
{
reset();
givenACodeSampleToTokenize manyScopes("AA::BB::CC::DD::EE* p;");
bool result = si.isVariableDeclaration(manyScopes.tokens(), vartok, typetok);
bool result = si.isVariableDeclaration(manyScopes.tokens(), vartok, typetok, isArray);
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("p", vartok->str());
ASSERT_EQUALS("EE", typetok->str());
ASSERT(false == isArray);
}
void test_isVariableDeclarationIdentifiesDeclarationWithIndirection()
{
reset();
givenACodeSampleToTokenize pointerToPointer("int** pp;");
bool result = si.isVariableDeclaration(pointerToPointer.tokens(), vartok, typetok);
bool result = si.isVariableDeclaration(pointerToPointer.tokens(), vartok, typetok, isArray);
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("pp", vartok->str());
ASSERT_EQUALS("int", typetok->str());
ASSERT(false == isArray);
}
void test_isVariableDeclarationIdentifiesDeclarationWithMultipleIndirection()
{
reset();
givenACodeSampleToTokenize pointerToPointer("int***** p;");
bool result = si.isVariableDeclaration(pointerToPointer.tokens(), vartok, typetok);
bool result = si.isVariableDeclaration(pointerToPointer.tokens(), vartok, typetok, isArray);
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("p", vartok->str());
ASSERT_EQUALS("int", typetok->str());
ASSERT(false == isArray);
}
void test_isVariableDeclarationIdentifiesArray()
{
reset();
givenACodeSampleToTokenize array("::std::string v[3];");
bool result = si.isVariableDeclaration(array.tokens(), vartok, typetok);
bool result = si.isVariableDeclaration(array.tokens(), vartok, typetok, isArray);
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("v", vartok->str());
ASSERT_EQUALS("string", typetok->str());
ASSERT(true == isArray);
}
void test_isVariableDeclarationIdentifiesOfArrayPointers()
{
reset();
givenACodeSampleToTokenize array("A *a[5];");
bool result = si.isVariableDeclaration(array.tokens(), vartok, typetok);
bool result = si.isVariableDeclaration(array.tokens(), vartok, typetok, isArray);
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("a", vartok->str());
ASSERT_EQUALS("A", typetok->str());
ASSERT(true == isArray);
}
void isVariableDeclarationIdentifiesTemplatedPointerVariable()
{
reset();
givenACodeSampleToTokenize var("std::set<char>* chars;");
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok);
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray);
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("chars", vartok->str());
ASSERT_EQUALS("set", typetok->str());
ASSERT(false == isArray);
}
void isVariableDeclarationIdentifiesTemplatedPointerToPointerVariable()
{
reset();
givenACodeSampleToTokenize var("std::deque<int>*** ints;");
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok);
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray);
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("ints", vartok->str());
ASSERT_EQUALS("deque", typetok->str());
ASSERT(false == isArray);
}
void isVariableDeclarationIdentifiesTemplatedArrayVariable()
{
reset();
givenACodeSampleToTokenize var("std::deque<int> ints[3];");
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok);
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray);
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("ints", vartok->str());
ASSERT_EQUALS("deque", typetok->str());
ASSERT(true == isArray);
}
void isVariableDeclarationIdentifiesTemplatedVariable()
{
reset();
givenACodeSampleToTokenize var("std::vector<int> ints;");
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok);
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray);
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("ints", vartok->str());
ASSERT_EQUALS("vector", typetok->str());
ASSERT(false == isArray);
}
void isVariableDeclarationIdentifiesTemplatedVariableIterator()
{
reset();
givenACodeSampleToTokenize var("std::list<int>::const_iterator floats;");
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok);
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray);
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("floats", vartok->str());
ASSERT_EQUALS("const_iterator", typetok->str());
ASSERT(false == isArray);
}
void isVariableDeclarationIdentifiesNestedTemplateVariable()
{
reset();
givenACodeSampleToTokenize var("std::deque<std::set<int> > intsets;");
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok);
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray);
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("intsets", vartok->str());
ASSERT_EQUALS("deque", typetok->str());
ASSERT(false == isArray);
}
void isVariableDeclarationDoesNotIdentifyTemplateClass()
{
reset();
givenACodeSampleToTokenize var("template <class T> class SomeClass{};");
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok);
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray);
ASSERT_EQUALS(false, result);
ASSERT(false == isArray);
}
void canFindMatchingBracketsNeedsOpen()