SymbolDatabase: Support std::array (fixes #6401)

This commit is contained in:
PKEuS 2015-01-30 21:56:27 +01:00
parent 03e44d4aa0
commit dcc1362890
3 changed files with 106 additions and 59 deletions

View File

@ -242,7 +242,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
new_scope->definedType = &typeList.back();
scope->definedTypes.push_back(&typeList.back());
scope->addVariable(varNameTok, tok, tok, access[scope], new_scope->definedType, scope);
scope->addVariable(varNameTok, tok, tok, access[scope], new_scope->definedType, scope, &settings->library);
const Token *tok2 = tok->next();
@ -800,9 +800,9 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
scope->nestedList.push_back(&scopeList.back());
scope = &scopeList.back();
if (scope->type == Scope::eFor)
scope->checkVariable(tok->tokAt(2), Local); // check for variable declaration and add it to new scope if found
scope->checkVariable(tok->tokAt(2), Local, &settings->library); // check for variable declaration and add it to new scope if found
else if (scope->type == Scope::eCatch)
scope->checkVariable(tok->tokAt(2), Throw); // check for variable declaration and add it to new scope if found
scope->checkVariable(tok->tokAt(2), Throw, &settings->library); // check for variable declaration and add it to new scope if found
tok = tok1;
} else if (tok->str() == "{" && !tok->previous()->varId()) {
if (tok->strAt(-1) == ")" && tok->linkAt(-1)->strAt(-1) == "]") {
@ -856,7 +856,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
// fill in variable info
for (std::list<Scope>::iterator it = scopeList.begin(); it != scopeList.end(); ++it) {
// find variables
it->getVariableList();
it->getVariableList(&settings->library);
}
// fill in function arguments
@ -1342,7 +1342,7 @@ const Token * Variable::declEndToken() const
return declEnd;
}
void Variable::evaluate()
void Variable::evaluate(const Library* lib)
{
const Token* tok = _start;
while (tok && tok->previous() && tok->previous()->isName())
@ -1380,7 +1380,7 @@ void Variable::evaluate()
_end = _end->previous();
if (_name)
setFlag(fIsArray, arrayDimensions(_dimensions, _name->next()));
setFlag(fIsArray, arrayDimensions(lib));
if (_start) {
setFlag(fIsClass, !_start->isStandardType() && !isPointer() && !isReference());
setFlag(fIsStlType, Token::simpleMatch(_start, "std ::"));
@ -1396,7 +1396,7 @@ void Variable::evaluate()
tok = tok->link()->previous();
// add array dimensions if present
if (tok && tok->next()->str() == "[")
setFlag(fIsArray, arrayDimensions(_dimensions, tok->next()));
setFlag(fIsArray, arrayDimensions(lib));
}
if (!tok)
return;
@ -1951,12 +1951,42 @@ bool Type::hasCircularDependencies(std::set<BaseInfo>* anchestors) const
return false;
}
bool Variable::arrayDimensions(std::vector<Dimension> &dimensions, const Token *tok)
bool Variable::arrayDimensions(const Library* lib)
{
const Library::Container* container = lib->detectContainer(_start);
if (container && container->arrayLike_indexOp && container->size_templateArgNo > 0) {
Dimension dimension;
const Token* tok = Token::findsimplematch(_start, "<");
if (tok) {
tok = tok->next();
for (int i = 0; i < container->size_templateArgNo && tok; i++) {
tok = tok->nextTemplateArgument();
}
if (tok) {
dimension.start = tok;
dimension.end = Token::findmatch(tok, ",|>");
if (dimension.end)
dimension.end = dimension.end->previous();
if (dimension.start == dimension.end)
dimension.num = MathLib::toLongNumber(dimension.start->str());
}
_dimensions.push_back(dimension);
return true;
}
}
const Token *dim = _name;
if (!dim) {
// Argument without name
dim = _end;
// back up to start of array dimensions
while (dim && dim->str() == "]")
dim = dim->link()->previous();
}
if (dim)
dim = dim->next();
bool isArray = false;
const Token *dim = tok;
while (dim && dim->next() && dim->str() == "[") {
Dimension dimension;
// check for empty array dimension []
@ -1966,7 +1996,7 @@ bool Variable::arrayDimensions(std::vector<Dimension> &dimensions, const Token *
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();
isArray = true;
}
@ -2452,7 +2482,7 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s
}
}
argumentList.push_back(Variable(nameTok, startTok, endTok, count++, Argument, argType, functionScope));
argumentList.push_back(Variable(nameTok, startTok, endTok, count++, Argument, argType, functionScope, &symbolDatabase->_settings->library));
if (tok->str() == ")")
break;
@ -2634,7 +2664,7 @@ AccessControl Scope::defaultAccess() const
}
// Get variable list..
void Scope::getVariableList()
void Scope::getVariableList(const Library* lib)
{
const Token *start;
@ -2748,14 +2778,14 @@ void Scope::getVariableList()
continue;
}
tok = checkVariable(tok, varaccess);
tok = checkVariable(tok, varaccess, lib);
if (!tok)
break;
}
}
const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess)
const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess, const Library* lib)
{
// Is it a throw..?
if (Token::Match(tok, "throw %any% (") &&
@ -2823,7 +2853,7 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess)
}
}
addVariable(vartok, typestart, vartok->previous(), varaccess, vType, this);
addVariable(vartok, typestart, vartok->previous(), varaccess, vType, this, lib);
}
return tok;

View File

@ -35,6 +35,7 @@
class Tokenizer;
class Settings;
class ErrorLogger;
class Library;
class Scope;
class SymbolDatabase;
@ -163,16 +164,15 @@ class CPPCHECKLIB Variable {
/**
* @brief parse and save array dimension information
* @param dimensions array dimensions vector
* @param tok the first '[' token of array declaration
* @param lib Library instance
* @return true if array, false if not
*/
static bool arrayDimensions(std::vector<Dimension> &dimensions, const Token *tok);
bool arrayDimensions(const Library* lib);
public:
Variable(const Token *name_, const Token *start_, const Token *end_,
std::size_t index_, AccessControl access_, const Type *type_,
const Scope *scope_)
const Scope *scope_, const Library* lib)
: _name(name_),
_start(start_),
_end(end_),
@ -181,7 +181,7 @@ public:
_flags(0),
_type(type_),
_scope(scope_) {
evaluate();
evaluate(lib);
}
/**
@ -553,7 +553,7 @@ private:
std::vector<Dimension> _dimensions;
/** @brief fill in information, depending on Tokens given at instantiation */
void evaluate();
void evaluate(const Library* lib);
};
class CPPCHECKLIB Function {
@ -857,14 +857,14 @@ public:
void addVariable(const Token *token_, const Token *start_,
const Token *end_, AccessControl access_, const Type *type_,
const Scope *scope_) {
const Scope *scope_, const Library* lib) {
varlist.push_back(Variable(token_, start_, end_, varlist.size(),
access_,
type_, scope_));
type_, scope_, lib));
}
/** @brief initialize varlist */
void getVariableList();
void getVariableList(const Library* lib);
const Function *getDestructor() const;
@ -892,9 +892,10 @@ public:
* @brief check if statement is variable declaration and add it if it is
* @param tok pointer to start of statement
* @param varaccess access control of statement
* @param lib Library instance
* @return pointer to last token
*/
const Token *checkVariable(const Token *tok, AccessControl varaccess);
const Token *checkVariable(const Token *tok, AccessControl varaccess, const Library* lib);
/**
* @brief get variable from name
@ -988,6 +989,7 @@ public:
private:
friend class Scope;
friend class Function;
void addClassFunction(Scope **info, const Token **tok, const Token *argStart);
Function *addGlobalFunctionDecl(Scope*& scope, const Token* tok, const Token *argStart, const Token* funcStart);

View File

@ -55,6 +55,7 @@ private:
const Token* typetok;
const Token* t;
bool found;
Settings settings;
void reset() {
vartok = nullptr;
@ -94,7 +95,10 @@ private:
}
void run() {
LOAD_LIB_2(settings.library, "std.cfg");
TEST_CASE(array);
TEST_CASE(stlarray);
TEST_CASE(test_isVariableDeclarationCanHandleNull);
TEST_CASE(test_isVariableDeclarationIdentifiesSimpleDeclaration);
@ -263,19 +267,30 @@ private:
TokenList list(nullptr);
list.createTokens(code, "test.c");
list.front()->tokAt(2)->link(list.front()->tokAt(6));
Variable v(list.front()->next(), list.front(), list.back(), 0, Public, nullptr, nullptr);
Variable v(list.front()->next(), list.front(), list.back(), 0, Public, nullptr, nullptr, &settings.library);
ASSERT(v.isArray());
ASSERT_EQUALS(1U, v.dimensions().size());
ASSERT_EQUALS(0U, v.dimension(0));
}
void stlarray() const {
std::istringstream code("std::array<int, 20> arr;");
TokenList list(nullptr);
list.createTokens(code, "test.c");
list.front()->tokAt(3)->link(list.front()->tokAt(7));
Variable v(list.front()->next(), list.front(), list.back(), 0, Public, nullptr, nullptr, &settings.library);
ASSERT(v.isArray());
ASSERT_EQUALS(1U, v.dimensions().size());
ASSERT_EQUALS(20U, v.dimension(0));
}
void test_isVariableDeclarationCanHandleNull() {
reset();
bool result = si.isVariableDeclaration(nullptr, vartok, typetok);
ASSERT_EQUALS(false, result);
ASSERT(nullptr == vartok);
ASSERT(nullptr == typetok);
Variable v(nullptr, nullptr, nullptr, 0, Public, 0, 0);
Variable v(nullptr, nullptr, nullptr, 0, Public, 0, 0, &settings.library);
}
void test_isVariableDeclarationIdentifiesSimpleDeclaration() {
@ -285,7 +300,7 @@ private:
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("x", vartok->str());
ASSERT_EQUALS("int", typetok->str());
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v.isArray());
ASSERT(false == v.isPointer());
ASSERT(false == v.isReference());
@ -298,7 +313,7 @@ private:
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("x", vartok->str());
ASSERT_EQUALS("int", typetok->str());
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v.isArray());
ASSERT(false == v.isPointer());
ASSERT(false == v.isReference());
@ -312,7 +327,7 @@ private:
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("x", vartok->str());
ASSERT_EQUALS("int", typetok->str());
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v.isArray());
ASSERT(false == v.isPointer());
ASSERT(false == v.isReference());
@ -326,7 +341,7 @@ private:
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("x", vartok->str());
ASSERT_EQUALS("int", typetok->str());
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v.isArray());
ASSERT(false == v.isPointer());
ASSERT(false == v.isReference());
@ -339,7 +354,7 @@ private:
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("x", vartok->str());
ASSERT_EQUALS("string", typetok->str());
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v.isArray());
ASSERT(false == v.isPointer());
ASSERT(false == v.isReference());
@ -352,7 +367,7 @@ private:
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("x", vartok->str());
ASSERT_EQUALS("string", typetok->str());
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v.isArray());
ASSERT(false == v.isPointer());
ASSERT(false == v.isReference());
@ -365,7 +380,7 @@ private:
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("x", vartok->str());
ASSERT_EQUALS("EE", typetok->str());
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v.isArray());
ASSERT(false == v.isPointer());
ASSERT(false == v.isReference());
@ -378,14 +393,14 @@ private:
ASSERT_EQUALS(true, result1);
ASSERT_EQUALS("p", vartok->str());
ASSERT_EQUALS("int", typetok->str());
Variable v1(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v1(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v1.isArray());
ASSERT(true == v1.isPointer());
ASSERT(false == v1.isReference());
reset();
givenACodeSampleToTokenize constpointer("const int* p;");
Variable v2(constpointer.tokens()->tokAt(3), constpointer.tokens()->next(), constpointer.tokens()->tokAt(2), 0, Public, 0, 0);
Variable v2(constpointer.tokens()->tokAt(3), constpointer.tokens()->next(), constpointer.tokens()->tokAt(2), 0, Public, 0, 0, &settings.library);
ASSERT(false == v2.isArray());
ASSERT(true == v2.isPointer());
ASSERT(false == v2.isConst());
@ -397,7 +412,7 @@ private:
ASSERT_EQUALS(true, result2);
ASSERT_EQUALS("p", vartok->str());
ASSERT_EQUALS("int", typetok->str());
Variable v3(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v3(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v3.isArray());
ASSERT(true == v3.isPointer());
ASSERT(true == v3.isConst());
@ -420,7 +435,7 @@ private:
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("first", vartok->str());
ASSERT_EQUALS("int", typetok->str());
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v.isArray());
ASSERT(false == v.isPointer());
ASSERT(false == v.isReference());
@ -433,7 +448,7 @@ private:
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("p", vartok->str());
ASSERT_EQUALS("EE", typetok->str());
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v.isArray());
ASSERT(true == v.isPointer());
ASSERT(false == v.isReference());
@ -446,7 +461,7 @@ private:
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("pp", vartok->str());
ASSERT_EQUALS("int", typetok->str());
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v.isArray());
ASSERT(true == v.isPointer());
ASSERT(false == v.isReference());
@ -459,7 +474,7 @@ private:
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("p", vartok->str());
ASSERT_EQUALS("int", typetok->str());
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v.isArray());
ASSERT(true == v.isPointer());
ASSERT(false == v.isReference());
@ -472,7 +487,7 @@ private:
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("v", vartok->str());
ASSERT_EQUALS("string", typetok->str());
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(true == v.isArray());
ASSERT(false == v.isPointer());
ASSERT(false == v.isReference());
@ -485,7 +500,7 @@ private:
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("a", vartok->str());
ASSERT_EQUALS("A", typetok->str());
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(true == v.isArray());
ASSERT(true == v.isPointer());
ASSERT(false == v.isReference());
@ -498,7 +513,7 @@ private:
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("chars", vartok->str());
ASSERT_EQUALS("set", typetok->str());
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v.isArray());
ASSERT(true == v.isPointer());
ASSERT(false == v.isReference());
@ -511,7 +526,7 @@ private:
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("ints", vartok->str());
ASSERT_EQUALS("deque", typetok->str());
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v.isArray());
ASSERT(true == v.isPointer());
ASSERT(false == v.isReference());
@ -524,7 +539,7 @@ private:
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("ints", vartok->str());
ASSERT_EQUALS("deque", typetok->str());
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(true == v.isArray());
ASSERT(false == v.isPointer());
ASSERT(false == v.isReference());
@ -537,7 +552,7 @@ private:
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("ints", vartok->str());
ASSERT_EQUALS("vector", typetok->str());
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v.isArray());
ASSERT(false == v.isPointer());
ASSERT(false == v.isReference());
@ -550,7 +565,7 @@ private:
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("floats", vartok->str());
ASSERT_EQUALS("const_iterator", typetok->str());
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v.isArray());
ASSERT(false == v.isPointer());
ASSERT(false == v.isReference());
@ -563,7 +578,7 @@ private:
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("intsets", vartok->str());
ASSERT_EQUALS("deque", typetok->str());
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v.isArray());
ASSERT(false == v.isPointer());
ASSERT(false == v.isReference());
@ -574,7 +589,7 @@ private:
givenACodeSampleToTokenize var1("int& foo;");
bool result1 = si.isVariableDeclaration(var1.tokens(), vartok, typetok);
ASSERT_EQUALS(true, result1);
Variable v1(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v1(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v1.isArray());
ASSERT(false == v1.isPointer());
ASSERT(true == v1.isReference());
@ -583,7 +598,7 @@ private:
givenACodeSampleToTokenize var2("foo*& bar;");
bool result2 = si.isVariableDeclaration(var2.tokens(), vartok, typetok);
ASSERT_EQUALS(true, result2);
Variable v2(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v2(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v2.isArray());
ASSERT(true == v2.isPointer());
ASSERT(true == v2.isReference());
@ -592,7 +607,7 @@ private:
givenACodeSampleToTokenize var3("std::vector<int>& foo;");
bool result3 = si.isVariableDeclaration(var3.tokens(), vartok, typetok);
ASSERT_EQUALS(true, result3);
Variable v3(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v3(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v3.isArray());
ASSERT(false == v3.isPointer());
ASSERT(true == v3.isReference());
@ -617,7 +632,7 @@ private:
givenACodeSampleToTokenize var("std::string const* s;");
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok);
ASSERT_EQUALS(true, result);
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v.isArray());
ASSERT(true == v.isPointer());
ASSERT(false == v.isReference());
@ -628,7 +643,7 @@ private:
givenACodeSampleToTokenize var("int&& i;");
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok);
ASSERT_EQUALS(true, result);
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v.isArray());
ASSERT(false == v.isPointer());
ASSERT(true == v.isReference());
@ -644,7 +659,7 @@ private:
list.createTokens(code, "test.cpp");
bool result = si.isVariableDeclaration(list.front(), vartok, typetok);
ASSERT_EQUALS(true, result);
Variable v(vartok, list.front(), list.back(), 0, Public, 0, 0);
Variable v(vartok, list.front(), list.back(), 0, Public, 0, 0, &settings.library);
const char* types[] = { "string", "wstring" };
const char* no_types[] = { "set" };
ASSERT_EQUALS(true, v.isStlType());
@ -660,7 +675,7 @@ private:
list.front()->tokAt(3)->link(list.front()->tokAt(5));
bool result = si.isVariableDeclaration(list.front(), vartok, typetok);
ASSERT_EQUALS(true, result);
Variable v(vartok, list.front(), list.back(), 0, Public, 0, 0);
Variable v(vartok, list.front(), list.back(), 0, Public, 0, 0, &settings.library);
const char* types[] = { "bitset", "set", "vector", "wstring" };
const char* no_types[] = { "bitset", "map", "set" };
ASSERT_EQUALS(true, v.isStlType());
@ -675,7 +690,7 @@ private:
list.createTokens(code, "test.cpp");
bool result = si.isVariableDeclaration(list.front(), vartok, typetok);
ASSERT_EQUALS(true, result);
Variable v(vartok, list.front(), list.back(), 0, Public, 0, 0);
Variable v(vartok, list.front(), list.back(), 0, Public, 0, 0, &settings.library);
const char* types[] = { "bitset", "set", "vector" };
ASSERT_EQUALS(false, v.isStlType());
ASSERT_EQUALS(false, v.isStlType(types));