This commit is contained in:
Tim Gerundt 2011-01-05 19:43:14 +01:00
commit de32cc6eab
3 changed files with 110 additions and 54 deletions

View File

@ -82,7 +82,9 @@ private:
_obsoleteFunctions.push_back(std::make_pair("fcvt","Found obsolete function 'fcvt'. It is recommended that new applications use the 'sprintf' function")); _obsoleteFunctions.push_back(std::make_pair("fcvt","Found obsolete function 'fcvt'. It is recommended that new applications use the 'sprintf' function"));
_obsoleteFunctions.push_back(std::make_pair("gcvt","Found obsolete function 'gcvt'. It is recommended that new applications use the 'sprintf' function")); _obsoleteFunctions.push_back(std::make_pair("gcvt","Found obsolete function 'gcvt'. It is recommended that new applications use the 'sprintf' function"));
_obsoleteFunctions.push_back(std::make_pair("ftime","Found obsolete function 'ftime'. It is recommended that new applications use the 'ftime' function. Realtime applications should use ''clock_gettime'' to determine the current time")); _obsoleteFunctions.push_back(std::make_pair("ftime","Found obsolete function 'ftime'.\n"
"It is recommended that new applications use time(), gettimeofday(), or clock_gettime() instead. "
"For high-resolution timing on Windows, QueryPerformanceCounter() and QueryPerformanceFrequency may be used."));
_obsoleteFunctions.push_back(std::make_pair("getcontext","Found obsolete function 'getcontext'. Due to portability issues with this function, applications are recommended to be rewritten to use POSIX threads")); _obsoleteFunctions.push_back(std::make_pair("getcontext","Found obsolete function 'getcontext'. Due to portability issues with this function, applications are recommended to be rewritten to use POSIX threads"));
_obsoleteFunctions.push_back(std::make_pair("makecontext","Found obsolete function 'makecontext'. Due to portability issues with this function, applications are recommended to be rewritten to use POSIX threads")); _obsoleteFunctions.push_back(std::make_pair("makecontext","Found obsolete function 'makecontext'. Due to portability issues with this function, applications are recommended to be rewritten to use POSIX threads"));

View File

@ -720,6 +720,78 @@ struct SpaceInfo
const Token * classEnd; const Token * classEnd;
}; };
static Token *splitDefinitionFromTypedef(Token *tok)
{
Token *tok1;
std::string name;
bool isConst = false;
if (tok->next()->str() == "const")
{
tok->next()->deleteThis();
isConst = true;
}
if (tok->tokAt(2)->str() == "{") // unnamed
{
tok1 = tok->tokAt(2)->link();
if (tok1 && tok1->next())
{
// use typedef name if available
if (Token::Match(tok1->next(), "%type%"))
name = tok1->next()->str();
else // create a unique name
{
static long count = 0;
name = "Unnamed" + MathLib::toString<long>(count++);
}
tok->tokAt(1)->insertToken(name.c_str());
}
else
return NULL;
}
else if (tok->strAt(3) == ":")
{
tok1 = tok->tokAt(4);
while (tok1 && tok1->str() != "{")
tok1 = tok1->next();
if (!tok1)
return NULL;
tok1 = tok1->link();
name = tok->tokAt(2)->str();
}
else // has a name
{
tok1 = tok->tokAt(3)->link();
if (!tok1)
return NULL;
name = tok->tokAt(2)->str();
}
tok1->insertToken(";");
tok1 = tok1->next();
tok1->insertToken("typedef");
tok1 = tok1->next();
Token * tok3 = tok1;
if (isConst)
{
tok1->insertToken("const");
tok1 = tok1->next();
}
tok1->insertToken(tok->next()->strAt(0)); // struct, union or enum
tok1 = tok1->next();
tok1->insertToken(name.c_str());
tok->deleteThis();
tok = tok3;
return tok;
}
void Tokenizer::simplifyTypedef() void Tokenizer::simplifyTypedef()
{ {
std::vector<SpaceInfo> spaceInfo; std::vector<SpaceInfo> spaceInfo;
@ -767,60 +839,23 @@ void Tokenizer::simplifyTypedef()
if (Token::Match(tok->next(), "const| struct|enum|union|class %type% {") || if (Token::Match(tok->next(), "const| struct|enum|union|class %type% {") ||
Token::Match(tok->next(), "const| struct|enum|union|class {")) Token::Match(tok->next(), "const| struct|enum|union|class {"))
{ {
Token *tok1; Token *tok1 = splitDefinitionFromTypedef(tok);
std::string name;
bool isConst = false;
if (tok->next()->str() == "const")
{
tok->next()->deleteThis();
isConst = true;
}
if (tok->tokAt(2)->str() == "{") // unnamed
{
tok1 = tok->tokAt(2)->link();
if (tok1 && tok1->next())
{
// use typedef name if available
if (Token::Match(tok1->next(), "%type%"))
name = tok1->next()->str();
else // create a unique name
{
static long count = 0;
name = "Unnamed" + MathLib::toString<long>(count++);
}
tok->tokAt(1)->insertToken(name.c_str());
}
else
continue;
}
else // has a name
{
tok1 = tok->tokAt(3)->link();
if (!tok1) if (!tok1)
continue; continue;
tok = tok1;
name = tok->tokAt(2)->str();
} }
else if (Token::Match(tok->next(), "const| struct|class %type% :"))
tok1->insertToken(";");
tok1 = tok1->next();
tok1->insertToken("typedef");
tok1 = tok1->next();
Token * tok3 = tok1;
if (isConst)
{ {
tok1->insertToken("const"); Token *tok1 = tok;
while (tok1 && tok1->str() != ";" && tok1->str() != "{")
tok1 = tok1->next(); tok1 = tok1->next();
if (tok1 && tok1->str() == "{")
{
tok1 = splitDefinitionFromTypedef(tok);
if (!tok1)
continue;
tok = tok1;
} }
tok1->insertToken(tok->next()->strAt(0)); // struct, union or enum
tok1 = tok1->next();
tok1->insertToken(name.c_str());
tok->deleteThis();
tok = tok3;
} }
/** @todo add support for struct and union */ /** @todo add support for struct and union */
@ -1645,9 +1680,12 @@ void Tokenizer::simplifyTypedef()
tok2 = tok2->next(); tok2 = tok2->next();
} }
// skip over variable name // skip over variable name if there
if (!inCast) if (!inCast)
{
if (tok2->next()->str() != ")")
tok2 = tok2->next(); tok2 = tok2->next();
}
if (tok4 && functionPtrRetFuncPtr) if (tok4 && functionPtrRetFuncPtr)
{ {
@ -4860,7 +4898,8 @@ bool Tokenizer::simplifyConditions()
else if (Token::simpleMatch(tok, "|| true )") || else if (Token::simpleMatch(tok, "|| true )") ||
Token::simpleMatch(tok, "&& false )")) Token::simpleMatch(tok, "&& false )"))
{ {
Token::eraseTokens(tok->tokAt(2)->link(), tok->next()); tok = tok->next();
Token::eraseTokens(tok->next()->link(), tok);
ret = true; ret = true;
} }

View File

@ -230,6 +230,7 @@ private:
TEST_CASE(simplifyTypedef70); // ticket #2348 TEST_CASE(simplifyTypedef70); // ticket #2348
TEST_CASE(simplifyTypedef71); // ticket #2348 TEST_CASE(simplifyTypedef71); // ticket #2348
TEST_CASE(simplifyTypedef72); // ticket #2375 TEST_CASE(simplifyTypedef72); // ticket #2375
TEST_CASE(simplifyTypedef73); // ticket #2412
TEST_CASE(simplifyTypedefFunction1); TEST_CASE(simplifyTypedefFunction1);
TEST_CASE(simplifyTypedefFunction2); // ticket #1685 TEST_CASE(simplifyTypedefFunction2); // ticket #1685
@ -4757,6 +4758,20 @@ private:
} }
} }
void simplifyTypedef73() // ticket #2412
{
const char code[] = "struct B {};\n"
"typedef struct A : public B {\n"
" void f();\n"
"} a, *aPtr;\n";
const std::string expected = "struct B { } ; "
"struct A : public B { "
"void f ( ) ; "
"} ;";
ASSERT_EQUALS(expected, sizeof_(code));
ASSERT_EQUALS("", errout.str());
}
void simplifyTypedefFunction1() void simplifyTypedefFunction1()
{ {
{ {