From 7cae057615d8c286e6f97a53d05eda0b77b525f5 Mon Sep 17 00:00:00 2001 From: IOBYTE Date: Thu, 30 Mar 2017 04:07:58 -0400 Subject: [PATCH] Add missing varid or variable for member variables. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an optional extended description… --- lib/symboldatabase.cpp | 32 ++++++++++++++++++++++++++++++++ lib/symboldatabase.h | 5 +++++ lib/tokenize.h | 9 +++++++++ test/testsymboldatabase.cpp | 30 +++++++++++++++--------------- 4 files changed, 61 insertions(+), 15 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 39ecdc360..bffaeb6ef 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1209,8 +1209,36 @@ void SymbolDatabase::createSymbolDatabaseSetTypePointers() } } +void SymbolDatabase::fixVarId(VarIdMap & varIds, const Token * vartok, Token * membertok, const Variable * membervar) +{ + VarIdMap::iterator varId = varIds.find(vartok->varId()); + if (varId == varIds.end()) { + MemberIdMap memberId; + if (membertok->varId() == 0) { + memberId[membervar->nameToken()->varId()] = const_cast(_tokenizer)->newVarId(); + _variableList.push_back(membervar); + } else + _variableList[membertok->varId()] = membervar; + varIds.insert(std::make_pair(vartok->varId(), memberId)); + varId = varIds.find(vartok->varId()); + } + MemberIdMap::iterator memberId = varId->second.find(membervar->nameToken()->varId()); + if (memberId == varId->second.end()) { + if (membertok->varId() == 0) { + varId->second.insert(std::make_pair(membervar->nameToken()->varId(), const_cast(_tokenizer)->newVarId())); + _variableList.push_back(membervar); + } else + _variableList[membertok->varId()] = membervar; + memberId = varId->second.find(membervar->nameToken()->varId()); + } + if (membertok->varId() == 0) + membertok->varId(memberId->second); +} + void SymbolDatabase::createSymbolDatabaseSetVariablePointers() { + VarIdMap varIds; + // Set variable pointers for (const Token* tok = _tokenizer->list.front(); tok != _tokenizer->list.back(); tok = tok->next()) { if (tok->varId()) @@ -1239,6 +1267,8 @@ void SymbolDatabase::createSymbolDatabaseSetVariablePointers() const Variable *membervar = var->typeScope()->getVariable(membertok->str()); if (membervar) { membertok->variable(membervar); + if (membertok->varId() == 0 || _variableList[membertok->varId()] == nullptr) + fixVarId(varIds, tok, const_cast(membertok), membervar); } } else if (var && tok->valueType() && tok->valueType()->type == ValueType::CONTAINER) { if (Token::Match(var->typeStartToken(), "std :: %type% < %type% *| *| >")) { @@ -1247,6 +1277,8 @@ void SymbolDatabase::createSymbolDatabaseSetVariablePointers() const Variable *membervar = type->classScope->getVariable(membertok->str()); if (membervar) { membertok->variable(membervar); + if (membertok->varId() == 0 || _variableList[membertok->varId()] == nullptr) + fixVarId(varIds, tok, const_cast(membertok), membervar); } } } diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 73f03aa6e..bde47bc77 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -1178,6 +1178,11 @@ private: Function *findFunctionInScope(const Token *func, const Scope *ns); const Type *findVariableTypeInBase(const Scope *scope, const Token *typeTok) const; + typedef std::map MemberIdMap; + typedef std::map VarIdMap; + + void fixVarId(VarIdMap & varIds, const Token * vartok, Token * membertok, const Variable * membervar); + /** Whether iName is a keyword as defined in http://en.cppreference.com/w/c/keyword and http://en.cppreference.com/w/cpp/keyword*/ bool isReservedName(const std::string& iName) const; diff --git a/lib/tokenize.h b/lib/tokenize.h index 1f3370d1e..95f8ac3ee 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -44,6 +44,7 @@ class CPPCHECKLIB Tokenizer { friend class TestSimplifyTokens; friend class TestSimplifyTypedef; friend class TestTokenizer; + friend class SymbolDatabase; public: Tokenizer(); Tokenizer(const Settings * settings, ErrorLogger *errorLogger); @@ -812,6 +813,14 @@ private: Token *processFunc(Token *tok2, bool inOperator) const; + /** + * Get new variable id. + * @return new variable id + */ + unsigned int newVarId() { + return ++_varId; + } + /** Set pod types */ void setPodTypes(); diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index d2f55e3f7..cd4d50297 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -817,7 +817,7 @@ private: tok = tok ? tok->next() : nullptr; ASSERT(db != nullptr); ASSERT(tok && tok->variable() && Token::simpleMatch(tok->variable()->typeStartToken(), "int x ;")); - ASSERT(tok && tok->varId() == 0U); // It's possible to set a varId + ASSERT(tok && tok->varId() == 3U); // It's possible to set a varId } void arrayMemberVar2() { @@ -833,7 +833,7 @@ private: tok = tok ? tok->next() : nullptr; ASSERT(db != nullptr); ASSERT(tok && tok->variable() && Token::simpleMatch(tok->variable()->typeStartToken(), "int x ;")); - ASSERT(tok && tok->varId() == 0U); // It's possible to set a varId + ASSERT(tok && tok->varId() == 3U); // It's possible to set a varId } void arrayMemberVar3() { @@ -849,7 +849,7 @@ private: tok = tok ? tok->next() : nullptr; ASSERT(db != nullptr); ASSERT(tok && tok->variable() && Token::simpleMatch(tok->variable()->typeStartToken(), "int x ;")); - ASSERT(tok && tok->varId() == 0U); // It's possible to set a varId + ASSERT(tok && tok->varId() == 3U); // It's possible to set a varId } void staticMemberVar() { @@ -4588,10 +4588,10 @@ private: vartok = Token::findsimplematch(tokenizer.tokens(), "return"); vartok = Token::findsimplematch(vartok, "i"); - TODO_ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); + ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); vartok = Token::findsimplematch(vartok->next(), "i"); - TODO_ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); + ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); vartok = Token::findsimplematch(vartok->next(), "i"); ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); @@ -4709,31 +4709,31 @@ private: ASSERT(db && vartok && vartok->variable() && !vartok->variable()->isPointer() && !vartok->variable()->isReference() && vartok->variable()->type() && vartok->variable()->type()->name() == "S"); vartok = Token::findsimplematch(vartok, "i"); - TODO_ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); + ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); vartok = Token::findsimplematch(vartok->next(), "b . i"); ASSERT(db && vartok && vartok->variable() && !vartok->variable()->isPointer() && vartok->variable()->isReference() && vartok->variable()->type() && vartok->variable()->type()->name() == "S"); vartok = Token::findsimplematch(vartok->next(), "i"); - TODO_ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); + ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); vartok = Token::findsimplematch(vartok->next(), "c . i"); ASSERT(db && vartok && vartok->variable() && !vartok->variable()->isPointer() && vartok->variable()->isReference() && vartok->variable()->type() && vartok->variable()->type()->name() == "S"); vartok = Token::findsimplematch(vartok->next(), "i"); - TODO_ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); + ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); vartok = Token::findsimplematch(vartok->next(), "d . i"); ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && !vartok->variable()->isReference() && vartok->variable()->type() && vartok->variable()->type()->name() == "S"); vartok = Token::findsimplematch(vartok->next(), "i"); - TODO_ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); + ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); vartok = Token::findsimplematch(vartok->next(), "e . i"); ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && !vartok->variable()->isReference() && vartok->variable()->type() && vartok->variable()->type()->name() == "S"); vartok = Token::findsimplematch(vartok->next(), "i"); - TODO_ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); + ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); vartok = Token::findsimplematch(vartok->next(), "i"); ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); @@ -4801,31 +4801,31 @@ private: ASSERT(db && vartok && vartok->variable() && !vartok->variable()->isPointer() && !vartok->variable()->isReference() && vartok->variable()->type() && vartok->variable()->type()->name() == "S"); vartok = Token::findsimplematch(vartok, "i"); - TODO_ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); + ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); vartok = Token::findsimplematch(vartok->next(), "b . i"); ASSERT(db && vartok && vartok->variable() && !vartok->variable()->isPointer() && vartok->variable()->isReference() && vartok->variable()->type() && vartok->variable()->type()->name() == "S"); vartok = Token::findsimplematch(vartok->next(), "i"); - TODO_ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); + ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); vartok = Token::findsimplematch(vartok->next(), "c . i"); ASSERT(db && vartok && vartok->variable() && !vartok->variable()->isPointer() && vartok->variable()->isReference() && vartok->variable()->type() && vartok->variable()->type()->name() == "S"); vartok = Token::findsimplematch(vartok->next(), "i"); - TODO_ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); + ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); vartok = Token::findsimplematch(vartok->next(), "d . i"); ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && !vartok->variable()->isReference() && vartok->variable()->type() && vartok->variable()->type()->name() == "S"); vartok = Token::findsimplematch(vartok->next(), "i"); - TODO_ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); + ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); vartok = Token::findsimplematch(vartok->next(), "e . i"); ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && !vartok->variable()->isReference() && vartok->variable()->type() && vartok->variable()->type()->name() == "S"); vartok = Token::findsimplematch(vartok->next(), "i"); - TODO_ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); + ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int"); vartok = Token::findsimplematch(vartok->next(), "i"); ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int");