CheckIO: Early return

This commit is contained in:
Daniel Marjamäki 2015-10-05 19:04:29 +02:00
parent 8f6bd7fd0d
commit bc8f1b972e
1 changed files with 105 additions and 103 deletions

View File

@ -1361,9 +1361,12 @@ CheckIO::ArgumentInfo::ArgumentInfo(const Token * tok, const Settings *settings,
, address(false) , address(false)
, isCPP(_isCPP) , isCPP(_isCPP)
{ {
if (!tok)
return;
// Use AST type info // Use AST type info
// TODO: This is a bailout so that old code is used in simple cases. Remove the old code and always use the AST type. // TODO: This is a bailout so that old code is used in simple cases. Remove the old code and always use the AST type.
if (tok && !Token::Match(tok, "&| %str%|%num%|%name% ,|)") && !Token::Match(tok, "%name% [|(|.|<|::|?")) { if (!Token::Match(tok, "&| %str%|%num%|%name% ,|)") && !Token::Match(tok, "%name% [|(|.|<|::|?")) {
const ValueType *valuetype = tok->argumentType(); const ValueType *valuetype = tok->argumentType();
if (valuetype && valuetype->type >= ValueType::Type::BOOL && !valuetype->pointer) { if (valuetype && valuetype->type >= ValueType::Type::BOOL && !valuetype->pointer) {
tempToken = new Token(0); tempToken = new Token(0);
@ -1388,130 +1391,129 @@ CheckIO::ArgumentInfo::ArgumentInfo(const Token * tok, const Settings *settings,
} }
} }
if (tok) {
if (tok->tokType() == Token::eString) { if (tok->tokType() == Token::eString) {
typeToken = tok; typeToken = tok;
return;
} else if (tok->str() == "&" || tok->tokType() == Token::eVariable ||
tok->tokType() == Token::eFunction || Token::Match(tok, "%type% ::") ||
(Token::Match(tok, "static_cast|reinterpret_cast|const_cast <") &&
Token::simpleMatch(tok->linkAt(1), "> (") &&
Token::Match(tok->linkAt(1)->linkAt(1), ") ,|)"))) {
if (Token::Match(tok, "static_cast|reinterpret_cast|const_cast")) {
typeToken = tok->tokAt(2);
while (typeToken->str() == "const" || typeToken->str() == "extern")
typeToken = typeToken->next();
return; return;
} else if (tok->str() == "&" || tok->tokType() == Token::eVariable || }
tok->tokType() == Token::eFunction || Token::Match(tok, "%type% ::") || if (tok->str() == "&") {
(Token::Match(tok, "static_cast|reinterpret_cast|const_cast <") && address = true;
Token::simpleMatch(tok->linkAt(1), "> (") && tok = tok->next();
Token::Match(tok->linkAt(1)->linkAt(1), ") ,|)"))) { }
if (Token::Match(tok, "static_cast|reinterpret_cast|const_cast")) { while (Token::Match(tok, "%type% ::"))
typeToken = tok->tokAt(2); tok = tok->tokAt(2);
while (typeToken->str() == "const" || typeToken->str() == "extern") if (!tok || !(tok->tokType() == Token::eVariable || tok->tokType() == Token::eFunction))
typeToken = typeToken->next(); return;
return; const Token *varTok = nullptr;
} const Token *tok1 = tok->next();
if (tok->str() == "&") { for (; tok1; tok1 = tok1->next()) {
address = true; if (tok1->str() == "," || tok1->str() == ")") {
tok = tok->next(); if (tok1->previous()->str() == "]") {
} varTok = tok1->linkAt(-1)->previous();
while (Token::Match(tok, "%type% ::")) if (varTok->str() == ")" && varTok->link()->previous()->tokType() == Token::eFunction) {
tok = tok->tokAt(2); const Function * function = varTok->link()->previous()->function();
if (!tok || !(tok->tokType() == Token::eVariable || tok->tokType() == Token::eFunction))
return;
const Token *varTok = nullptr;
const Token *tok1 = tok->next();
for (; tok1; tok1 = tok1->next()) {
if (tok1->str() == "," || tok1->str() == ")") {
if (tok1->previous()->str() == "]") {
varTok = tok1->linkAt(-1)->previous();
if (varTok->str() == ")" && varTok->link()->previous()->tokType() == Token::eFunction) {
const Function * function = varTok->link()->previous()->function();
if (function && function->retDef) {
typeToken = function->retDef;
while (typeToken->str() == "const" || typeToken->str() == "extern")
typeToken = typeToken->next();
functionInfo = function;
element = true;
}
return;
}
} else if (tok1->previous()->str() == ")" && tok1->linkAt(-1)->previous()->tokType() == Token::eFunction) {
const Function * function = tok1->linkAt(-1)->previous()->function();
if (function && function->retDef) { if (function && function->retDef) {
typeToken = function->retDef; typeToken = function->retDef;
while (typeToken->str() == "const" || typeToken->str() == "extern") while (typeToken->str() == "const" || typeToken->str() == "extern")
typeToken = typeToken->next(); typeToken = typeToken->next();
functionInfo = function; functionInfo = function;
element = false; element = true;
} }
return; return;
} else
varTok = tok1->previous();
break;
} else if (tok1->str() == "(" || tok1->str() == "{" || tok1->str() == "[")
tok1 = tok1->link();
else if (tok1->link() && tok1->str() == "<")
tok1 = tok1->link();
// check for some common well known functions
else if (isCPP && ((Token::Match(tok1->previous(), "%var% . size|empty|c_str ( ) [,)]") && isStdContainer(tok1->previous())) ||
(Token::Match(tok1->previous(), "] . size|empty|c_str ( ) [,)]") && isStdContainer(tok1->previous()->link()->previous())))) {
tempToken = new Token(0);
tempToken->fileIndex(tok1->fileIndex());
tempToken->linenr(tok1->linenr());
if (tok1->next()->str() == "size") {
// size_t is platform dependent
if (settings->sizeof_size_t == 8) {
tempToken->str("long");
if (settings->sizeof_long != 8)
tempToken->isLong(true);
} else if (settings->sizeof_size_t == 4) {
if (settings->sizeof_long == 4) {
tempToken->str("long");
} else {
tempToken->str("int");
}
}
tempToken->originalName("size_t");
tempToken->isUnsigned(true);
} else if (tok1->next()->str() == "empty") {
tempToken->str("bool");
} else if (tok1->next()->str() == "c_str") {
tempToken->str("const");
tempToken->insertToken("*");
if (typeToken->strAt(2) == "string")
tempToken->insertToken("char");
else
tempToken->insertToken("wchar_t");
} }
typeToken = tempToken; } else if (tok1->previous()->str() == ")" && tok1->linkAt(-1)->previous()->tokType() == Token::eFunction) {
const Function * function = tok1->linkAt(-1)->previous()->function();
if (function && function->retDef) {
typeToken = function->retDef;
while (typeToken->str() == "const" || typeToken->str() == "extern")
typeToken = typeToken->next();
functionInfo = function;
element = false;
}
return; return;
} } else
// check for std::vector::at() and std::string::at()
else if (Token::Match(tok1->previous(), "%var% . at (") &&
Token::Match(tok1->linkAt(2), ") [,)]")) {
varTok = tok1->previous(); varTok = tok1->previous();
variableInfo = varTok->variable(); break;
} else if (tok1->str() == "(" || tok1->str() == "{" || tok1->str() == "[")
tok1 = tok1->link();
else if (tok1->link() && tok1->str() == "<")
tok1 = tok1->link();
if (!variableInfo || !isStdVectorOrString()) { // check for some common well known functions
variableInfo = 0; else if (isCPP && ((Token::Match(tok1->previous(), "%var% . size|empty|c_str ( ) [,)]") && isStdContainer(tok1->previous())) ||
typeToken = 0; (Token::Match(tok1->previous(), "] . size|empty|c_str ( ) [,)]") && isStdContainer(tok1->previous()->link()->previous())))) {
tempToken = new Token(0);
tempToken->fileIndex(tok1->fileIndex());
tempToken->linenr(tok1->linenr());
if (tok1->next()->str() == "size") {
// size_t is platform dependent
if (settings->sizeof_size_t == 8) {
tempToken->str("long");
if (settings->sizeof_long != 8)
tempToken->isLong(true);
} else if (settings->sizeof_size_t == 4) {
if (settings->sizeof_long == 4) {
tempToken->str("long");
} else {
tempToken->str("int");
}
} }
return; tempToken->originalName("size_t");
} else if (!(tok1->str() == "." || tok1->tokType() == Token::eVariable || tok1->tokType() == Token::eFunction)) tempToken->isUnsigned(true);
return; } else if (tok1->next()->str() == "empty") {
tempToken->str("bool");
} else if (tok1->next()->str() == "c_str") {
tempToken->str("const");
tempToken->insertToken("*");
if (typeToken->strAt(2) == "string")
tempToken->insertToken("char");
else
tempToken->insertToken("wchar_t");
}
typeToken = tempToken;
return;
} }
if (varTok) { // check for std::vector::at() and std::string::at()
else if (Token::Match(tok1->previous(), "%var% . at (") &&
Token::Match(tok1->linkAt(2), ") [,)]")) {
varTok = tok1->previous();
variableInfo = varTok->variable(); variableInfo = varTok->variable();
element = tok1->previous()->str() == "]";
// look for std::vector operator [] and use template type as return type if (!variableInfo || !isStdVectorOrString()) {
if (variableInfo) { variableInfo = 0;
if (element && isStdVectorOrString()) { // isStdVectorOrString sets type token if true typeToken = 0;
element = false; // not really an array element
} else
typeToken = variableInfo->typeStartToken();
} }
return; return;
} else if (!(tok1->str() == "." || tok1->tokType() == Token::eVariable || tok1->tokType() == Token::eFunction))
return;
}
if (varTok) {
variableInfo = varTok->variable();
element = tok1->previous()->str() == "]";
// look for std::vector operator [] and use template type as return type
if (variableInfo) {
if (element && isStdVectorOrString()) { // isStdVectorOrString sets type token if true
element = false; // not really an array element
} else
typeToken = variableInfo->typeStartToken();
} }
return;
} }
} }
} }