fix #1982 (simplifyTypedef: scope info is lost)
This commit is contained in:
parent
d998477c69
commit
51baca0359
|
@ -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())
|
||||||
|
|
|
@ -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()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue