symbol database: add preliminary support for throw/catch block scopes. Just like the rest of cppcheck, ... is not handled properly for variables. Deep namespaces are also not handled properly yet. This is not an issue because this new capability is not used by any checks so it should be harmless.
This commit is contained in:
parent
42a75692d4
commit
6b0aff487f
|
@ -545,6 +545,22 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
|||
tok = tok1;
|
||||
scope = &scopeList.back();
|
||||
scope->nestedIn->nestedList.push_back(scope);
|
||||
} else if (Token::simpleMatch(tok, "try {")) {
|
||||
const Token *tok1 = tok->next();
|
||||
scopeList.push_back(Scope(this, tok, scope, Scope::eTry, tok1));
|
||||
tok = tok1;
|
||||
scope = &scopeList.back();
|
||||
scope->nestedIn->nestedList.push_back(scope);
|
||||
} else if (Token::simpleMatch(tok, "catch (") &&
|
||||
Token::simpleMatch(tok->next()->link(), ") {")) {
|
||||
const Token *tok1 = tok->next()->link()->next();
|
||||
const Token *tok2 = tok->tokAt(2);
|
||||
scopeList.push_back(Scope(this, tok, scope, Scope::eCatch, tok1));
|
||||
tok = tok1;
|
||||
scope = &scopeList.back();
|
||||
scope->nestedIn->nestedList.push_back(scope);
|
||||
// check for variable declaration and add it to new scope if found
|
||||
scope->checkVariable(tok2, Throw);
|
||||
} else if (tok->str() == "{") {
|
||||
if (!Token::Match(tok->previous(), "=|,")) {
|
||||
scopeList.push_back(Scope(this, tok, scope, Scope::eUnconditional, tok));
|
||||
|
@ -1228,6 +1244,8 @@ static std::ostream & operator << (std::ostream & s, Scope::ScopeType type)
|
|||
type == Scope::eWhile ? "While" :
|
||||
type == Scope::eDo ? "Do" :
|
||||
type == Scope::eSwitch ? "Switch" :
|
||||
type == Scope::eTry ? "Try" :
|
||||
type == Scope::eCatch ? "Catch" :
|
||||
type == Scope::eUnconditional ? "Unconditional" :
|
||||
"Unknown");
|
||||
return s;
|
||||
|
@ -1254,6 +1272,7 @@ void SymbolDatabase::printVariable(const Variable *var, const char *indent) cons
|
|||
var->isNamespace() ? "Namespace" :
|
||||
var->isArgument() ? "Argument" :
|
||||
var->isLocal() ? "Local" :
|
||||
var->isThrow() ? "Throw" :
|
||||
"???") << std::endl;
|
||||
std::cout << indent << "_flags: " << std::endl;
|
||||
std::cout << indent << " isMutable: " << (var->isMutable() ? "true" : "false") << std::endl;
|
||||
|
@ -1766,6 +1785,15 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess)
|
|||
const Token *vartok = NULL;
|
||||
const Token *typetok = NULL;
|
||||
|
||||
// Is it a throw..?
|
||||
if (Token::Match(tok, "throw %any% (") &&
|
||||
Token::simpleMatch(tok->linkAt(2), ") ;")) {
|
||||
return tok->linkAt(2);
|
||||
} else if ((Token::Match(tok, "throw %any% :: %any% (") &&
|
||||
Token::simpleMatch(tok->linkAt(4), ") ;"))) {
|
||||
return tok->linkAt(4);
|
||||
}
|
||||
|
||||
// Is it const..?
|
||||
bool isConst = false;
|
||||
if (tok->str() == "const") {
|
||||
|
@ -1903,7 +1931,14 @@ bool Scope::isVariableDeclaration(const Token* tok, const Token*& vartok, const
|
|||
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"));
|
||||
|
||||
return NULL != vartok;
|
||||
|
|
|
@ -39,7 +39,7 @@ class SymbolDatabase;
|
|||
/**
|
||||
* @brief Access control enumerations.
|
||||
*/
|
||||
enum AccessControl { Public, Protected, Private, Global, Namespace, Argument, Local };
|
||||
enum AccessControl { Public, Protected, Private, Global, Namespace, Argument, Local, Throw };
|
||||
|
||||
/**
|
||||
* @brief Array dimension information.
|
||||
|
@ -245,6 +245,14 @@ public:
|
|||
return getFlag(fIsConst);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is variable a throw type.
|
||||
* @return true if throw type, false if not
|
||||
*/
|
||||
bool isThrow() const {
|
||||
return _access == Throw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is variable a user defined (or unknown) type.
|
||||
* @return true if user defined type, false if not
|
||||
|
@ -407,7 +415,7 @@ public:
|
|||
Scope *scope;
|
||||
};
|
||||
|
||||
enum ScopeType { eGlobal, eClass, eStruct, eUnion, eNamespace, eFunction, eIf, eElse, eElseIf, eFor, eWhile, eDo, eSwitch, eUnconditional };
|
||||
enum ScopeType { eGlobal, eClass, eStruct, eUnion, eNamespace, eFunction, eIf, eElse, eElseIf, eFor, eWhile, eDo, eSwitch, eUnconditional, eTry, eCatch };
|
||||
enum NeedInitialization { Unknown, True, False };
|
||||
|
||||
Scope(SymbolDatabase *check_, const Token *classDef_, Scope *nestedIn_);
|
||||
|
|
Loading…
Reference in New Issue