Refactoring: Check if type is class/struct through symbol database

This commit is contained in:
Daniel Marjamäki 2011-01-16 19:57:29 +01:00
parent e6a1efa13b
commit 93d1313186
4 changed files with 25 additions and 13 deletions

View File

@ -21,6 +21,7 @@
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#include "checkautovariables.h" #include "checkautovariables.h"
#include "symboldatabase.h"
#include <sstream> #include <sstream>
#include <iostream> #include <iostream>
@ -140,6 +141,8 @@ void CheckAutoVariables::autoVariables()
// Which variables have an unknown type? // Which variables have an unknown type?
std::set<unsigned int> unknown_type; std::set<unsigned int> unknown_type;
const SymbolDatabase * const symbolDatabase = _tokenizer->getSymbolDatabase();
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{ {
@ -192,7 +195,7 @@ void CheckAutoVariables::autoVariables()
{ {
addVD(tok->next()->varId()); addVD(tok->next()->varId());
if (!tok->isStandardType() && if (!tok->isStandardType() &&
NULL == Token::findmatch(_tokenizer->tokens(), ("struct|class " + tok->str()).c_str())) !symbolDatabase->isClassOrStruct(tok->str()))
{ {
unknown_type.insert(tok->next()->varId()); unknown_type.insert(tok->next()->varId());
} }

View File

@ -2100,6 +2100,8 @@ void CheckOther::checkConstantFunctionParameter()
if (!_settings->_checkCodingStyle) if (!_settings->_checkCodingStyle)
return; return;
const SymbolDatabase * const symbolDatabase = _tokenizer->getSymbolDatabase();
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{ {
if (Token::Match(tok, "[,(] const std :: %type% %var% [,)]")) if (Token::Match(tok, "[,(] const std :: %type% %var% [,)]"))
@ -2140,8 +2142,7 @@ void CheckOther::checkConstantFunctionParameter()
else if (Token::Match(tok, "[,(] const %type% %var% [,)]")) else if (Token::Match(tok, "[,(] const %type% %var% [,)]"))
{ {
// Check if type is a struct or class. // Check if type is a struct or class.
const std::string pattern(std::string("class|struct ") + tok->strAt(2)); if (symbolDatabase->isClassOrStruct(tok->strAt(2)))
if (Token::findmatch(_tokenizer->tokens(), pattern.c_str()))
{ {
passedByValueError(tok, tok->strAt(3)); passedByValueError(tok, tok->strAt(3));
} }
@ -2529,18 +2530,10 @@ void CheckOther::checkMisusedScopedObject()
return; return;
} }
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase * const symbolDatabase = _tokenizer->getSymbolDatabase();
std::list<SymbolDatabase::SpaceInfo *>::const_iterator i; std::list<SymbolDatabase::SpaceInfo *>::const_iterator i;
// list of classes / structs
std::set<std::string> identifiers;
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{
if (Token::Match(tok, "class|struct %var% [:{;]"))
identifiers.insert(tok->next()->str());
}
for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i)
{ {
const SymbolDatabase::SpaceInfo *info = *i; const SymbolDatabase::SpaceInfo *info = *i;
@ -2566,7 +2559,7 @@ void CheckOther::checkMisusedScopedObject()
if (Token::Match(tok, "[;{}] %var% (") if (Token::Match(tok, "[;{}] %var% (")
&& Token::Match(tok->tokAt(2)->link(), ") ;") && Token::Match(tok->tokAt(2)->link(), ") ;")
&& identifiers.find(tok->next()->str()) != identifiers.end() && symbolDatabase->isClassOrStruct(tok->next()->str())
) )
{ {
tok = tok->next(); tok = tok->next();

View File

@ -38,6 +38,13 @@
SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
: _tokenizer(tokenizer), _settings(settings), _errorLogger(errorLogger) : _tokenizer(tokenizer), _settings(settings), _errorLogger(errorLogger)
{ {
// fill the classAndStructTypes set..
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{
if (Token::Match(tok, "class|struct %var% [:{;]"))
classAndStructTypes.insert(tok->next()->str());
}
// find all namespaces (class,struct and namespace) // find all namespaces (class,struct and namespace)
SpaceInfo *info = new SpaceInfo(this, NULL, NULL); SpaceInfo *info = new SpaceInfo(this, NULL, NULL);
spaceInfoList.push_back(info); spaceInfoList.push_back(info);

View File

@ -24,6 +24,7 @@
#include <string> #include <string>
#include <list> #include <list>
#include <vector> #include <vector>
#include <set>
class Token; class Token;
class Tokenizer; class Tokenizer;
@ -223,6 +224,11 @@ public:
bool argsMatch(const SpaceInfo *info, const Token *first, const Token *second, const std::string &path, unsigned int depth) const; bool argsMatch(const SpaceInfo *info, const Token *first, const Token *second, const std::string &path, unsigned int depth) const;
bool isClassOrStruct(const std::string &type) const
{
return bool(classAndStructTypes.find(type) != classAndStructTypes.end());
}
private: private:
// Needed by Borland C++: // Needed by Borland C++:
@ -233,6 +239,9 @@ private:
const Token *initBaseInfo(SpaceInfo *info, const Token *tok); const Token *initBaseInfo(SpaceInfo *info, const Token *tok);
bool isFunction(const Token *tok, const Token **funcStart, const Token **argStart) const; bool isFunction(const Token *tok, const Token **funcStart, const Token **argStart) const;
/** class/struct types */
std::set<std::string> classAndStructTypes;
const Tokenizer *_tokenizer; const Tokenizer *_tokenizer;
const Settings *_settings; const Settings *_settings;
ErrorLogger *_errorLogger; ErrorLogger *_errorLogger;