fix #1982 (simplifyTypedef: scope info is lost)

This commit is contained in:
Robert Reif 2011-05-02 22:42:52 -04:00
parent d998477c69
commit 51baca0359
2 changed files with 96 additions and 0 deletions

View File

@ -1395,6 +1395,7 @@ void Tokenizer::simplifyTypedef()
bool simplifyType = false; bool simplifyType = false;
bool inMemberFunc = false; bool inMemberFunc = false;
int memberScope = 0; int memberScope = 0;
bool globalScope = false;
std::size_t classLevel = spaceInfo.size(); std::size_t classLevel = spaceInfo.size();
for (Token *tok2 = tok; tok2; tok2 = tok2->next()) for (Token *tok2 = tok; tok2; tok2 = tok2->next())
@ -1517,6 +1518,12 @@ void Tokenizer::simplifyTypedef()
if (pattern1.find("::") != std::string::npos) // has a "something ::" if (pattern1.find("::") != std::string::npos) // has a "something ::"
{ {
if (Token::simpleMatch(tok2->previous(), "::"))
{
tok2->previous()->previous()->deleteNext();
globalScope = true;
}
for (std::size_t i = classLevel; i < spaceInfo.size(); i++) for (std::size_t i = classLevel; i < spaceInfo.size(); i++)
{ {
tok2->deleteNext(); tok2->deleteNext();
@ -1615,11 +1622,39 @@ void Tokenizer::simplifyTypedef()
inOperator = true; inOperator = true;
// skip over class or struct in derived class declaration // skip over class or struct in derived class declaration
bool structRemoved = false;
if (isDerived && Token::Match(typeStart, "class|struct")) if (isDerived && Token::Match(typeStart, "class|struct"))
{
if (typeStart->str() == "struct")
structRemoved = true;
typeStart = typeStart->next(); typeStart = typeStart->next();
}
// start substituting at the typedef name by replacing it with the type // start substituting at the typedef name by replacing it with the type
tok2->str(typeStart->str()); tok2->str(typeStart->str());
// restore qualification if it was removed
if (typeStart->str() == "struct" || structRemoved)
{
if (structRemoved)
tok2 = tok2->previous();
if (globalScope)
{
tok2->insertToken("::");
tok2 = tok2->next();
}
for (std::size_t i = classLevel; i < spaceInfo.size(); i++)
{
tok2->insertToken(spaceInfo[i].className);
tok2 = tok2->next();
tok2->insertToken("::");
tok2 = tok2->next();
}
}
// add remainder of type
tok2 = copyTokens(tok2, typeStart->next(), typeEnd); tok2 = copyTokens(tok2, typeStart->next(), typeEnd);
if (!pointers.empty()) if (!pointers.empty())

View File

@ -258,6 +258,7 @@ private:
TEST_CASE(simplifyTypedef91); // ticket #2716 TEST_CASE(simplifyTypedef91); // ticket #2716
TEST_CASE(simplifyTypedef92); // ticket #2736 TEST_CASE(simplifyTypedef92); // ticket #2736
TEST_CASE(simplifyTypedef93); // ticket #2738 TEST_CASE(simplifyTypedef93); // ticket #2738
TEST_CASE(simplifyTypedef94); // ticket #1982
TEST_CASE(simplifyTypedefFunction1); TEST_CASE(simplifyTypedefFunction1);
TEST_CASE(simplifyTypedefFunction2); // ticket #1685 TEST_CASE(simplifyTypedefFunction2); // ticket #1685
@ -5255,6 +5256,66 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void simplifyTypedef94() // ticket #1982
{
const char code1[] = "class A {\n"
"public:\n"
" typedef struct {\n"
" int a[4];\n"
" } data;\n"
"};\n"
"A::data d;\n";
const char expected1[] = "class A { "
"public: "
"struct data { "
"int a [ 4 ] ; "
"} ; "
"} ; "
"struct A :: data d ;";
checkSimplifyTypedef(code1);
ASSERT_EQUALS(expected1, sizeof_(code1));
TODO_ASSERT_EQUALS("[test.cpp:7]: (debug) Scope::checkVariable found variable 'd' with varid 0.\n", "", errout.str());
const char code2[] = "class A {\n"
"public:\n"
" typedef struct {\n"
" int a[4];\n"
" } data;\n"
"};\n"
"::A::data d;\n";
const char expected2[] = "class A { "
"public: "
"struct data { "
"int a [ 4 ] ; "
"} ; "
"} ; "
"struct :: A :: data d ;";
checkSimplifyTypedef(code2);
ASSERT_EQUALS(expected2, sizeof_(code2));
TODO_ASSERT_EQUALS("[test.cpp:7]: (debug) Scope::checkVariable found variable 'd' with varid 0.\n", "", errout.str());
const char code3[] = "class A {\n"
"public:\n"
" typedef struct {\n"
" int a[4];\n"
" } data;\n"
"};\n"
"class B : public ::A::data { };\n";
const char expected3[] = "class A { "
"public: "
"struct data { "
"int a [ 4 ] ; "
"} ; "
"} ; "
"class B : public :: A :: data { } ;";
checkSimplifyTypedef(code3);
ASSERT_EQUALS(expected3, sizeof_(code3));
ASSERT_EQUALS("", errout.str());
}
void simplifyTypedefFunction1() void simplifyTypedefFunction1()
{ {
{ {