diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 23b735266..71b4c6814 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -121,25 +121,14 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti Scope *new_scope = &scopeList.back(); access[new_scope] = Public; - std::vector dimensions; - - bool isPointer = false; - bool isReference = false; - bool isArray = false; - const Token* varNameTok = tok->next()->link()->next(); if (varNameTok->str() == "*") { - isPointer = true; varNameTok = varNameTok->next(); } else if (varNameTok->str() == "&") { - isReference = true; varNameTok = varNameTok->next(); } - if (varNameTok->next()->str() == "[") - isArray = arrayDimensions(dimensions, varNameTok->next()); - - scope->addVariable(varNameTok, tok, tok, access[scope], false, false, false, true, new_scope, scope, isArray, isPointer, isReference, dimensions); + scope->addVariable(varNameTok, tok, tok, access[scope], new_scope, scope); const Token *tok2 = tok->next(); @@ -817,6 +806,39 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const return false; } +void Variable::evaluate() +{ + const Token* tok = _start; + if (tok && tok->previous() && tok->previous()->isName()) + tok = tok->previous(); + for (; tok != _name; tok = tok->next()) { + if (tok->str() == "<") + tok->findClosingBracket(tok); + if (tok->str() == "static") + setFlag(fIsStatic, true); + else if (tok->str() == "mutable") + setFlag(fIsMutable, true); + else if (tok->str() == "const") + setFlag(fIsConst, true); + else if (tok->str() == "*") { + setFlag(fIsPointer, true); + setFlag(fIsConst, false); // Points to const, isn't necessarily const itself + } else if (tok->str() == "&") + setFlag(fIsReference, true); + } + + if (_name) + setFlag(fIsArray, arrayDimensions(_dimensions, _name->next())); + if (_start) + setFlag(fIsClass, !_start->isStandardType() && !isPointer() && !isReference()); + if (_access == Argument && _name) { + const Token* tok = _name->next(); + while (tok->str() == "[") + tok = tok->link(); + setFlag(fHasDefault, tok->str() == "="); + } +} + bool Function::argsMatch(const Scope *scope, const Token *first, const Token *second, const std::string &path, unsigned int depth) { while (first->str() == second->str()) { @@ -1233,7 +1255,7 @@ void SymbolDatabase::debugMessage(const Token *tok, const std::string &msg) cons } } -bool SymbolDatabase::arrayDimensions(std::vector &dimensions, const Token *tok) const +bool Variable::arrayDimensions(std::vector &dimensions, const Token *tok) { bool isArray = false; @@ -1524,18 +1546,12 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s const Token* startTok = tok; const Token* endTok = NULL; const Token* nameTok = NULL; - bool isConstVar = bool(tok->str() == "const"); - bool isArrayVar = false; - bool hasDefault = false; - std::vector dimensions; while (tok->str() != "," && tok->str() != ")" && tok->str() != "=") { if (tok->varId() != 0) { nameTok = tok; endTok = tok->previous(); } else if (tok->str() == "[") { - isArrayVar = symbolDatabase->arrayDimensions(dimensions, tok); - // skip array dimension(s) tok = tok->link(); while (tok->next()->str() == "[") @@ -1552,7 +1568,7 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s return; } - const Token *typeTok = startTok->tokAt(isConstVar ? 1 : 0); + const Token *typeTok = startTok->tokAt(startTok->str() == "const" ? 1 : 0); if (typeTok->str() == "struct") typeTok = typeTok->next(); @@ -1575,19 +1591,13 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s if (!typeTok->isStandardType()) argType = symbolDatabase->findVariableType(scope, typeTok); - bool isClassVar = startTok == endTok && !startTok->isStandardType(); - bool isPointerVar = nameTok->strAt(-1) == "*" || nameTok->strAt(-2) == "*"; - bool isReferenceVar = nameTok->strAt(-1) == "&"; - // skip default values if (tok->str() == "=") { - hasDefault = true; - while (tok->str() != "," && tok->str() != ")") tok = tok->next(); } - argumentList.push_back(Variable(nameTok, startTok, endTok, count++, Argument, false, false, isConstVar, isClassVar, argType, functionScope, isArrayVar, isPointerVar, isReferenceVar, hasDefault, dimensions)); + argumentList.push_back(Variable(nameTok, startTok, endTok, count++, Argument, argType, functionScope)); if (tok->str() == ")") break; @@ -1883,56 +1893,38 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess) } // Is it const..? - bool isConst(tok->str() == "const"); - if (isConst) { + if (tok->str() == "const") { tok = tok->next(); } // Is it a static variable? - const bool isStatic(tok->str() == "static"); - if (isStatic) { + if (tok->str() == "static") { tok = tok->next(); } // Is it a mutable variable? - const bool isMutable(tok->str() == "mutable"); - if (isMutable) { + if (tok->str() == "mutable") { tok = tok->next(); } // Is it const..? if (tok->str() == "const") { tok = tok->next(); - isConst = true; } // the start of the type tokens does not include the above modifiers const Token *typestart = tok; - bool isClass = false; - if (Token::Match(tok, "struct|union")) { tok = tok->next(); } - bool isArray = false; - bool isPointer = false; - bool isReference = false; - std::vector dimensions; + if (tok && isVariableDeclaration(tok, vartok, typetok)) { + // If the vartok was set in the if-blocks above, create a entry for this variable.. + tok = vartok->next(); + while (tok && tok->str() == "[") + tok = tok->link()->next(); - if (tok && isVariableDeclaration(tok, vartok, typetok, isArray, isPointer, isReference)) { - isClass = (!typetok->isStandardType() && !isPointer && vartok->previous()->str() != "&"); - 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 (vartok && vartok->str() != "operator") { if (vartok->varId() == 0 && !vartok->isBoolean()) check->debugMessage(vartok, "Scope::checkVariable found variable \'" + vartok->str() + "\' with varid 0."); @@ -1941,7 +1933,7 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess) if (typetok) scope = check->findVariableType(this, typetok); - addVariable(vartok, typestart, vartok->previous(), varaccess, isMutable, isStatic, isConst, isClass, scope, this, isArray, isPointer, isReference, dimensions); + addVariable(vartok, typestart, vartok->previous(), varaccess, scope, this); } return tok; @@ -1980,7 +1972,7 @@ static const Token* skipPointers(const Token* tok) return tok; } -bool Scope::isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok, bool &isArray, bool &isPointer, bool &isReference) const +bool Scope::isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const { if (tok && tok->str() == "throw" && check->_tokenizer->isCPP()) return false; @@ -2006,28 +1998,21 @@ bool Scope::isVariableDeclaration(const Token* tok, const Token*& vartok, const if (Token::Match(localVarTok, "%var% ;|=")) { vartok = localVarTok; typetok = localTypeTok; - isArray = false; } else if (Token::Match(localVarTok, "%var% [") && localVarTok->str() != "operator") { vartok = localVarTok; typetok = localTypeTok; - isArray = true; } else if ((isLocal() || type == Scope::eFunction) && Token::Match(localVarTok, "%var% (") && Token::simpleMatch(localVarTok->next()->link(), ") ;")) { vartok = localVarTok; typetok = localTypeTok; - isArray = false; } else if (type == eCatch && (Token::Match(localTypeTok, "%var% )") || Token::Match(localTypeTok, "%var% &| %var% )"))) { vartok = localVarTok; typetok = localTypeTok; - isArray = false; } - isPointer = vartok && (vartok->strAt(-1) == "*" || Token::simpleMatch(vartok->tokAt(-2), "* const")); - isReference = vartok && vartok->strAt(-1) == "&"; - return NULL != vartok; } diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 70a1c9728..8509c90e7 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -84,12 +84,18 @@ class Variable { _flags = state_ ? _flags | flag_ : _flags & ~flag_; } + /** + * @brief parse and save array dimension information + * @param dimensions array dimensions vector + * @param tok the first '[' token of array declaration + * @return true if array, false if not + */ + static bool arrayDimensions(std::vector &dimensions, const Token *tok); + 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_, bool array_, bool pointer_, bool reference_, - bool default_, const std::vector &dimensions_) + std::size_t index_, AccessControl access_, const Scope *type_, + const Scope *scope_) : _name(name_), _start(start_), _end(end_), @@ -98,15 +104,7 @@ public: _flags(0), _type(type_), _scope(scope_) { - setFlag(fIsMutable, mutable_); - setFlag(fIsStatic, static_); - setFlag(fIsConst, const_); - setFlag(fIsClass, class_); - setFlag(fIsArray, array_); - setFlag(fIsPointer, pointer_); - setFlag(fIsReference, reference_); - setFlag(fHasDefault, default_); - _dimensions = dimensions_; + evaluate(); } /** @@ -354,6 +352,9 @@ private: /** @brief array dimensions */ std::vector _dimensions; + + /** @brief fill in information, depending on Tokens given at instanciation */ + void evaluate(); }; class Function { @@ -384,7 +385,6 @@ public: std::size_t argCount() const { return argumentList.size(); } - /** @brief get a pointer to the variable instance associated with the given argument number */ const Variable* getArgumentVar(unsigned int num) const; unsigned int initializedArgCount() const; void addArguments(const SymbolDatabase *symbolDatabase, const Scope *scope); @@ -486,13 +486,11 @@ public: const Scope * findQualifiedScope(const std::string & name) const; 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_, bool array_, bool pointer_, bool reference_, - const std::vector &dimensions_) { + const Token *end_, AccessControl access_, const Scope *type_, + const Scope *scope_) { varlist.push_back(Variable(token_, start_, end_, varlist.size(), - access_, mutable_, static_, const_, class_, - type_, scope_, array_, pointer_, reference_, false, dimensions_)); + access_, + type_, scope_)); } /** @brief initialize varlist */ @@ -537,7 +535,7 @@ private: * @param isPointer reference to variable to set if pointer is found * @return true if tok points to a variable declaration, false otherwise */ - bool isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok, bool &isArray, bool &isPointer, bool &isReference) const; + bool isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const; }; class SymbolDatabase { @@ -578,14 +576,6 @@ public: */ void debugMessage(const Token *tok, const std::string &msg) const; - /** - * @brief parse and save array dimension information - * @param dimensions array dimensions vector - * @param tok the first '[' token of array declaration - * @return true if array, false if not - */ - bool arrayDimensions(std::vector &dimensions, const Token *tok) const; - void printOut(const char * title = NULL) const; void printVariable(const Variable *var, const char *indent) const; diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index e2f2b24f1..75d1a2b8c 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -44,31 +44,21 @@ public: ,vartok(NULL) ,typetok(NULL) ,t(NULL) - ,isArray(false) - ,isPointer(false) - ,isReference(false) + ,found(false) {} - virtual void reportOut(const std::string &outmsg) { - errout << outmsg << std::endl; - } - private: const Scope si; const Token* vartok; const Token* typetok; const Token* t; - bool isArray; - bool isPointer; - bool isReference; + bool found; void reset() { vartok = NULL; typetok = NULL; t = NULL; - isArray = false; - isPointer = false; - isReference = false; + found = false; } void run() { @@ -157,287 +147,301 @@ private: void test_isVariableDeclarationCanHandleNull() { reset(); - bool result = si.isVariableDeclaration(NULL, vartok, typetok, isArray, isPointer, isReference); + bool result = si.isVariableDeclaration(NULL, vartok, typetok); ASSERT_EQUALS(false, result); ASSERT(NULL == vartok); ASSERT(NULL == typetok); - ASSERT(false == isArray); - ASSERT(false == isPointer); - ASSERT(false == isReference); + Variable v(NULL, NULL, NULL, 0, Public, 0, 0); } void test_isVariableDeclarationIdentifiesSimpleDeclaration() { reset(); givenACodeSampleToTokenize simpleDeclaration("int x;"); - bool result = si.isVariableDeclaration(simpleDeclaration.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result = si.isVariableDeclaration(simpleDeclaration.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); ASSERT_EQUALS("x", vartok->str()); ASSERT_EQUALS("int", typetok->str()); - ASSERT(false == isArray); - ASSERT(false == isPointer); - ASSERT(false == isReference); + Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0); + ASSERT(false == v.isArray()); + ASSERT(false == v.isPointer()); + ASSERT(false == v.isReference()); } void test_isVariableDeclarationIdentifiesScopedDeclaration() { reset(); givenACodeSampleToTokenize ScopedDeclaration("::int x;"); - bool result = si.isVariableDeclaration(ScopedDeclaration.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result = si.isVariableDeclaration(ScopedDeclaration.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); ASSERT_EQUALS("x", vartok->str()); ASSERT_EQUALS("int", typetok->str()); - ASSERT(false == isArray); - ASSERT(false == isPointer); - ASSERT(false == isReference); + Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0); + ASSERT(false == v.isArray()); + ASSERT(false == v.isPointer()); + ASSERT(false == v.isReference()); } void test_isVariableDeclarationIdentifiesStdDeclaration() { reset(); givenACodeSampleToTokenize StdDeclaration("std::string x;"); - bool result = si.isVariableDeclaration(StdDeclaration.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result = si.isVariableDeclaration(StdDeclaration.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); ASSERT_EQUALS("x", vartok->str()); ASSERT_EQUALS("string", typetok->str()); - ASSERT(false == isArray); - ASSERT(false == isPointer); - ASSERT(false == isReference); + Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0); + ASSERT(false == v.isArray()); + ASSERT(false == v.isPointer()); + ASSERT(false == v.isReference()); } void test_isVariableDeclarationIdentifiesScopedStdDeclaration() { reset(); givenACodeSampleToTokenize StdDeclaration("::std::string x;"); - bool result = si.isVariableDeclaration(StdDeclaration.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result = si.isVariableDeclaration(StdDeclaration.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); ASSERT_EQUALS("x", vartok->str()); ASSERT_EQUALS("string", typetok->str()); - ASSERT(false == isArray); - ASSERT(false == isPointer); - ASSERT(false == isReference); + Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0); + ASSERT(false == v.isArray()); + ASSERT(false == v.isPointer()); + ASSERT(false == v.isReference()); } void test_isVariableDeclarationIdentifiesManyScopes() { reset(); givenACodeSampleToTokenize manyScopes("AA::BB::CC::DD::EE x;"); - bool result = si.isVariableDeclaration(manyScopes.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result = si.isVariableDeclaration(manyScopes.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); ASSERT_EQUALS("x", vartok->str()); ASSERT_EQUALS("EE", typetok->str()); - ASSERT(false == isArray); - ASSERT(false == isPointer); - ASSERT(false == isReference); + Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0); + ASSERT(false == v.isArray()); + ASSERT(false == v.isPointer()); + ASSERT(false == v.isReference()); } void test_isVariableDeclarationIdentifiesPointers() { reset(); givenACodeSampleToTokenize pointer("int* p;"); - bool result = si.isVariableDeclaration(pointer.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result = si.isVariableDeclaration(pointer.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); ASSERT_EQUALS("p", vartok->str()); ASSERT_EQUALS("int", typetok->str()); - ASSERT(false == isArray); - ASSERT(true == isPointer); - ASSERT(false == isReference); + Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0); + ASSERT(false == v.isArray()); + ASSERT(true == v.isPointer()); + ASSERT(false == v.isReference()); } void test_isVariableDeclarationDoesNotIdentifyConstness() { reset(); givenACodeSampleToTokenize constness("const int* cp;"); - bool result = si.isVariableDeclaration(constness.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result = si.isVariableDeclaration(constness.tokens(), vartok, typetok); ASSERT_EQUALS(false, result); ASSERT(NULL == vartok); ASSERT(NULL == typetok); - ASSERT(false == isArray); - ASSERT(false == isPointer); - ASSERT(false == isReference); } void test_isVariableDeclarationIdentifiesFirstOfManyVariables() { reset(); givenACodeSampleToTokenize multipleDeclaration("int first, second;"); - bool result = si.isVariableDeclaration(multipleDeclaration.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result = si.isVariableDeclaration(multipleDeclaration.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); ASSERT_EQUALS("first", vartok->str()); ASSERT_EQUALS("int", typetok->str()); - ASSERT(false == isArray); - ASSERT(false == isPointer); - ASSERT(false == isReference); + Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0); + ASSERT(false == v.isArray()); + ASSERT(false == v.isPointer()); + ASSERT(false == v.isReference()); } void test_isVariableDeclarationIdentifiesScopedPointerDeclaration() { reset(); givenACodeSampleToTokenize manyScopes("AA::BB::CC::DD::EE* p;"); - bool result = si.isVariableDeclaration(manyScopes.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result = si.isVariableDeclaration(manyScopes.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); ASSERT_EQUALS("p", vartok->str()); ASSERT_EQUALS("EE", typetok->str()); - ASSERT(false == isArray); - ASSERT(true == isPointer); - ASSERT(false == isReference); + Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0); + ASSERT(false == v.isArray()); + ASSERT(true == v.isPointer()); + ASSERT(false == v.isReference()); } void test_isVariableDeclarationIdentifiesDeclarationWithIndirection() { reset(); givenACodeSampleToTokenize pointerToPointer("int** pp;"); - bool result = si.isVariableDeclaration(pointerToPointer.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result = si.isVariableDeclaration(pointerToPointer.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); ASSERT_EQUALS("pp", vartok->str()); ASSERT_EQUALS("int", typetok->str()); - ASSERT(false == isArray); - ASSERT(true == isPointer); - ASSERT(false == isReference); + Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0); + ASSERT(false == v.isArray()); + ASSERT(true == v.isPointer()); + ASSERT(false == v.isReference()); } void test_isVariableDeclarationIdentifiesDeclarationWithMultipleIndirection() { reset(); givenACodeSampleToTokenize pointerToPointer("int***** p;"); - bool result = si.isVariableDeclaration(pointerToPointer.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result = si.isVariableDeclaration(pointerToPointer.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); ASSERT_EQUALS("p", vartok->str()); ASSERT_EQUALS("int", typetok->str()); - ASSERT(false == isArray); - ASSERT(true == isPointer); - ASSERT(false == isReference); + Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0); + ASSERT(false == v.isArray()); + ASSERT(true == v.isPointer()); + ASSERT(false == v.isReference()); } void test_isVariableDeclarationIdentifiesArray() { reset(); givenACodeSampleToTokenize array("::std::string v[3];"); - bool result = si.isVariableDeclaration(array.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result = si.isVariableDeclaration(array.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); ASSERT_EQUALS("v", vartok->str()); ASSERT_EQUALS("string", typetok->str()); - ASSERT(true == isArray); - ASSERT(false == isPointer); - ASSERT(false == isReference); + Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0); + ASSERT(true == v.isArray()); + ASSERT(false == v.isPointer()); + ASSERT(false == v.isReference()); } void test_isVariableDeclarationIdentifiesOfArrayPointers() { reset(); givenACodeSampleToTokenize array("A *a[5];"); - bool result = si.isVariableDeclaration(array.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result = si.isVariableDeclaration(array.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); ASSERT_EQUALS("a", vartok->str()); ASSERT_EQUALS("A", typetok->str()); - ASSERT(true == isArray); - ASSERT(true == isPointer); - ASSERT(false == isReference); + Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0); + ASSERT(true == v.isArray()); + ASSERT(true == v.isPointer()); + ASSERT(false == v.isReference()); } void isVariableDeclarationIdentifiesTemplatedPointerVariable() { reset(); givenACodeSampleToTokenize var("std::set* chars;"); - bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); ASSERT_EQUALS("chars", vartok->str()); ASSERT_EQUALS("set", typetok->str()); - ASSERT(false == isArray); - ASSERT(true == isPointer); - ASSERT(false == isReference); + Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0); + ASSERT(false == v.isArray()); + ASSERT(true == v.isPointer()); + ASSERT(false == v.isReference()); } void isVariableDeclarationIdentifiesTemplatedPointerToPointerVariable() { reset(); givenACodeSampleToTokenize var("std::deque*** ints;"); - bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); ASSERT_EQUALS("ints", vartok->str()); ASSERT_EQUALS("deque", typetok->str()); - ASSERT(false == isArray); - ASSERT(true == isPointer); - ASSERT(false == isReference); + Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0); + ASSERT(false == v.isArray()); + ASSERT(true == v.isPointer()); + ASSERT(false == v.isReference()); } void isVariableDeclarationIdentifiesTemplatedArrayVariable() { reset(); givenACodeSampleToTokenize var("std::deque ints[3];"); - bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); ASSERT_EQUALS("ints", vartok->str()); ASSERT_EQUALS("deque", typetok->str()); - ASSERT(true == isArray); - ASSERT(false == isPointer); - ASSERT(false == isReference); + Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0); + ASSERT(true == v.isArray()); + ASSERT(false == v.isPointer()); + ASSERT(false == v.isReference()); } void isVariableDeclarationIdentifiesTemplatedVariable() { reset(); givenACodeSampleToTokenize var("std::vector ints;"); - bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); ASSERT_EQUALS("ints", vartok->str()); ASSERT_EQUALS("vector", typetok->str()); - ASSERT(false == isArray); - ASSERT(false == isPointer); - ASSERT(false == isReference); + Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0); + ASSERT(false == v.isArray()); + ASSERT(false == v.isPointer()); + ASSERT(false == v.isReference()); } void isVariableDeclarationIdentifiesTemplatedVariableIterator() { reset(); givenACodeSampleToTokenize var("std::list::const_iterator floats;"); - bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); ASSERT_EQUALS("floats", vartok->str()); ASSERT_EQUALS("const_iterator", typetok->str()); - ASSERT(false == isArray); - ASSERT(false == isPointer); - ASSERT(false == isReference); + Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0); + ASSERT(false == v.isArray()); + ASSERT(false == v.isPointer()); + ASSERT(false == v.isReference()); } void isVariableDeclarationIdentifiesNestedTemplateVariable() { reset(); givenACodeSampleToTokenize var("std::deque > intsets;"); - bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); ASSERT_EQUALS("intsets", vartok->str()); ASSERT_EQUALS("deque", typetok->str()); - ASSERT(false == isArray); - ASSERT(false == isPointer); - ASSERT(false == isReference); + Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0); + ASSERT(false == v.isArray()); + ASSERT(false == v.isPointer()); + ASSERT(false == v.isReference()); } void isVariableDeclarationIdentifiesReference() { reset(); givenACodeSampleToTokenize var1("int& foo;"); - bool result1 = si.isVariableDeclaration(var1.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result1 = si.isVariableDeclaration(var1.tokens(), vartok, typetok); ASSERT_EQUALS(true, result1); - ASSERT(false == isArray); - ASSERT(false == isPointer); - ASSERT(true == isReference); + Variable v1(vartok, typetok, vartok->previous(), 0, Public, 0, 0); + ASSERT(false == v1.isArray()); + ASSERT(false == v1.isPointer()); + ASSERT(true == v1.isReference()); reset(); givenACodeSampleToTokenize var2("foo*& bar;"); - bool result2 = si.isVariableDeclaration(var2.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result2 = si.isVariableDeclaration(var2.tokens(), vartok, typetok); ASSERT_EQUALS(true, result2); - ASSERT(false == isArray); - ASSERT(false == isPointer); - ASSERT(true == isReference); + Variable v2(vartok, typetok, vartok->previous(), 0, Public, 0, 0); + ASSERT(false == v2.isArray()); + ASSERT(true == v2.isPointer()); + ASSERT(true == v2.isReference()); reset(); givenACodeSampleToTokenize var3("std::vector& foo;"); - bool result3 = si.isVariableDeclaration(var3.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result3 = si.isVariableDeclaration(var3.tokens(), vartok, typetok); ASSERT_EQUALS(true, result3); - ASSERT(false == isArray); - ASSERT(false == isPointer); - ASSERT(true == isReference); + Variable v3(vartok, typetok, vartok->previous(), 0, Public, 0, 0); + ASSERT(false == v3.isArray()); + ASSERT(false == v3.isPointer()); + ASSERT(true == v3.isReference()); } void isVariableDeclarationDoesNotIdentifyTemplateClass() { reset(); givenACodeSampleToTokenize var("template class SomeClass{};"); - bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok); ASSERT_EQUALS(false, result); - ASSERT(false == isArray); - ASSERT(false == isPointer); - ASSERT(false == isReference); } void isVariableDeclarationPointerConst() { reset(); givenACodeSampleToTokenize var("std::string const* s;"); - bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer, isReference); + bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); - ASSERT(false == isArray); - ASSERT(true == isPointer); - ASSERT(false == isReference); + Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0); + ASSERT(false == v.isArray()); + ASSERT(true == v.isPointer()); + ASSERT(false == v.isReference()); } void hasRegularFunction() { @@ -450,12 +454,14 @@ private: const Scope *scope = db->findFunctionScopeByToken(tokenizer.tokens()->next()); ASSERT(scope && scope->className == "func"); + ASSERT(scope && scope->functionOf == 0); const Function *function = db->findFunctionByToken(tokenizer.tokens()->next()); ASSERT(function && function->token->str() == "func"); ASSERT(function && function->token == tokenizer.tokens()->next()); ASSERT(function && function->hasBody); + ASSERT(function && function->functionScope == scope && scope->function == function); } } @@ -469,12 +475,14 @@ private: const Scope *scope = db->findFunctionScopeByToken(tokenizer.tokens()->tokAt(4)); ASSERT(scope && scope->className == "func"); + ASSERT(scope && scope->functionOf && scope->functionOf == db->findScopeByName("Fred")); const Function *function = db->findFunctionByToken(tokenizer.tokens()->tokAt(4)); ASSERT(function && function->token->str() == "func"); ASSERT(function && function->token == tokenizer.tokens()->tokAt(4)); ASSERT(function && function->hasBody && function->isInline); + ASSERT(function && function->functionScope == scope && scope->function == function); } } @@ -507,12 +515,14 @@ private: const Scope *scope = db->findFunctionScopeByToken(tokenizer.tokens()->tokAt(12)); ASSERT(scope && scope->className == "func"); + ASSERT(scope && scope->functionOf && scope->functionOf == db->findScopeByName("Fred")); const Function *function = db->findFunctionByToken(tokenizer.tokens()->tokAt(12)); ASSERT(function && function->token->str() == "func"); ASSERT(function && function->token == tokenizer.tokens()->tokAt(12)); ASSERT(function && function->hasBody && !function->isInline); + ASSERT(function && function->functionScope == scope && scope->function == function); } } @@ -712,13 +722,26 @@ private: } void functionArgs1() { - check("void f(std::vector, const std::vector & v) { }\n"); - - ASSERT_EQUALS("", errout.str()); - - check("void f(std::map > m) { }\n"); - - ASSERT_EQUALS("", errout.str()); + { + GET_SYMBOL_DB("void f(std::vector, const std::vector & v) { }"); + TODO_ASSERT_EQUALS(1+1, 1+2, db->getVariableListSize()); + const Variable* v = db->getVariableFromVarId(2); // TODO: varId 1 + ASSERT(v && v->isReference() && v->isConst() && v->isArgument()); + const Scope* f = db->findScopeByName("f"); + ASSERT(f && f->type == Scope::eFunction && f->function); + if (f && f->function) + ASSERT(f->function->argumentList.size() == 2 && f->function->argumentList.front().index() == 0 && f->function->argumentList.front().name() == "" && f->function->argumentList.back().index() == 1); + ASSERT_EQUALS("", errout.str()); + } + { + GET_SYMBOL_DB("void g(std::map > m) { }"); + ASSERT_EQUALS(1+1, db->getVariableListSize()); + const Variable* m = db->getVariableFromVarId(1); + ASSERT(m && !m->isReference() && !m->isConst() && m->isArgument() && m->isClass()); + const Scope* g = db->findScopeByName("g"); + ASSERT(g && g->type == Scope::eFunction && g->function && g->function->argumentList.size() == 1 && g->function->argumentList.front().index() == 0); + ASSERT_EQUALS("", errout.str()); + } } void functionArgs2() {