Skip to content

Commit

Permalink
refactor, improve
Browse files Browse the repository at this point in the history
  • Loading branch information
danmar committed Dec 1, 2024
1 parent 6c81d70 commit a6e65eb
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 91 deletions.
156 changes: 67 additions & 89 deletions lib/tokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1180,6 +1180,24 @@ void Tokenizer::simplifyTypedef()
simplifyTypedefCpp();
}

static Token* simplifyTypedefCopyTokens(Token* to, const Token* fromStart, const Token* toEnd, const Token* location) {
Token* ret = TokenList::copyTokens(to, fromStart, toEnd);
for (Token* tok = to->next(); tok != ret->next(); tok = tok->next()) {
tok->linenr(location->linenr());
tok->column(location->column());
tok->isSimplifiedTypedef(true);
}
return ret;
}

static Token* simplifyTypedefInsertToken(Token* tok, const std::string& str, const Token* location) {
tok = tok->insertToken(str);
tok->linenr(location->linenr());
tok->column(location->column());
tok->isSimplifiedTypedef(true);
return tok;
}

// TODO: rename - it is not C++ specific
void Tokenizer::simplifyTypedefCpp()
{
Expand Down Expand Up @@ -1999,14 +2017,13 @@ void Tokenizer::simplifyTypedefCpp()
const bool isPointerTypeCall = !inOperator && Token::Match(tok2, "%name% ( )") && !pointers.empty();

// start substituting at the typedef name by replacing it with the type
Token* replStart = tok2; // track first replaced token
const Token * const location = tok2;
for (Token* tok3 = typeStart; tok3 && (tok3->str() != ";"); tok3 = tok3->next())
tok3->isSimplifiedTypedef(true);
if (isPointerTypeCall) {
tok2->deleteThis();
tok2->insertToken("0");
tok2 = tok2->next();
tok2->next()->insertToken("0");
tok2 = simplifyTypedefInsertToken(tok2, "0", location);
simplifyTypedefInsertToken(tok2->next(), "0", location);
}
if (Token::Match(tok2->tokAt(-1), "class|struct|union") && tok2->strAt(-1) == typeStart->str())
tok2->deletePrevious();
Expand All @@ -2018,15 +2035,12 @@ void Tokenizer::simplifyTypedefCpp()
tok2 = tok2->previous();

if (globalScope) {
replStart = tok2->insertToken("::");
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, "::", location);
}

for (std::size_t i = classLevel; i < spaceInfo.size(); ++i) {
tok2->insertToken(spaceInfo[i].className);
tok2 = tok2->next();
tok2->insertToken("::");
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, spaceInfo[i].className, location);
tok2 = simplifyTypedefInsertToken(tok2, "::", location);
}
}

Expand All @@ -2043,11 +2057,11 @@ void Tokenizer::simplifyTypedefCpp()
std::string::size_type spaceIdx = 0;
std::string::size_type startIdx = 0;
while ((spaceIdx = removed1.find(' ', startIdx)) != std::string::npos) {
tok2->previous()->insertToken(removed1.substr(startIdx, spaceIdx - startIdx));
simplifyTypedefInsertToken(tok2->previous(), removed1.substr(startIdx, spaceIdx - startIdx), location);
startIdx = spaceIdx + 1;
}
tok2->previous()->insertToken(removed1.substr(startIdx));
replStart = tok2->previous()->insertToken("::");
simplifyTypedefInsertToken(tok2->previous(), removed1.substr(startIdx), location);
simplifyTypedefInsertToken(tok2->previous(), "::", location);
break;
}
idx = removed1.rfind(" ::");
Expand All @@ -2059,31 +2073,21 @@ void Tokenizer::simplifyTypedefCpp()
}
Token* constTok = Token::simpleMatch(tok2->previous(), "const") ? tok2->previous() : nullptr;
// add remainder of type
tok2 = TokenList::copyTokens(tok2, typeStart->next(), typeEnd);
for (Token* tok3 = replStart; tok3 != tok2->next(); tok3 = tok3->next()) {
tok3->column(replStart->column());
tok3->isSimplifiedTypedef(true);
}
tok2 = simplifyTypedefCopyTokens(tok2, typeStart->next(), typeEnd, location);

if (!pointers.empty()) {
for (const std::string &p : pointers) {
tok2->insertToken(p);
tok2->isSimplifiedTypedef(true);
tok2 = tok2->next();
}
for (const std::string &p : pointers)
tok2 = simplifyTypedefInsertToken(tok2, p, location);
if (constTok) {
constTok->deleteThis();
tok2->insertToken("const");
tok2->isSimplifiedTypedef(true);
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, "const", location);
}
}

if (funcStart && funcEnd) {
tok2->insertToken("(");
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, "(", location);
Token *paren = tok2;
tok2 = TokenList::copyTokens(tok2, funcStart, funcEnd);
tok2 = simplifyTypedefCopyTokens(tok2, funcStart, funcEnd, location);

if (!inCast)
tok2 = processFunc(tok2, inOperator);
Expand All @@ -2094,20 +2098,17 @@ void Tokenizer::simplifyTypedefCpp()
while (Token::Match(tok2, "%name%|] ["))
tok2 = tok2->linkAt(1);

tok2->insertToken(")");
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, ")", location);
Token::createMutualLinks(tok2, paren);

tok2 = TokenList::copyTokens(tok2, argStart, argEnd);
tok2 = simplifyTypedefCopyTokens(tok2, argStart, argEnd, location);

if (specStart) {
Token *spec = specStart;
tok2->insertToken(spec->str());
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, spec->str(), location);
while (spec != specEnd) {
spec = spec->next();
tok2->insertToken(spec->str());
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, spec->str(), location);
}
}
}
Expand All @@ -2119,24 +2120,20 @@ void Tokenizer::simplifyTypedefCpp()
if (!inTemplate && function && tok2->next() && tok2->strAt(1) != "*")
needParen = false;
if (needParen) {
tok2->insertToken("(");
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, "(", location);
}
Token *tok3 = tok2;
if (namespaceStart) {
const Token *tok4 = namespaceStart;

while (tok4 != namespaceEnd) {
tok2->insertToken(tok4->str());
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, tok4->str(), location);
tok4 = tok4->next();
}
tok2->insertToken(namespaceEnd->str());
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, namespaceEnd->str(), location);
}
if (functionPtr) {
tok2->insertToken("*");
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, "*", location);
}

if (!inCast)
Expand All @@ -2146,42 +2143,35 @@ void Tokenizer::simplifyTypedefCpp()
if (!tok2)
syntaxError(nullptr);

tok2->insertToken(")");
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, ")", location);
Token::createMutualLinks(tok2, tok3);
}
if (!tok2)
syntaxError(nullptr);

tok2 = TokenList::copyTokens(tok2, argStart, argEnd);
tok2 = simplifyTypedefCopyTokens(tok2, argStart, argEnd, location);
if (inTemplate) {
tok2 = tok2->next();
}

if (specStart) {
Token *spec = specStart;
tok2->insertToken(spec->str());
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, spec->str(), location);
while (spec != specEnd) {
spec = spec->next();
tok2->insertToken(spec->str());
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, spec->str(), location);
}
}
} else if (functionRetFuncPtr || functionPtrRetFuncPtr) {
tok2->insertToken("(");
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, "(", location);
Token *tok3 = tok2;
tok2->insertToken("*");
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, "*", location);

Token * tok4 = nullptr;
if (functionPtrRetFuncPtr) {
tok2->insertToken("(");
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, "(", location);
tok4 = tok2;
tok2->insertToken("*");
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, "*", location);
}

// skip over variable name if there
Expand All @@ -2194,28 +2184,24 @@ void Tokenizer::simplifyTypedefCpp()
}

if (tok4 && functionPtrRetFuncPtr) {
tok2->insertToken(")");
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2,")", location);
Token::createMutualLinks(tok2, tok4);
}

tok2 = TokenList::copyTokens(tok2, argStart, argEnd);
tok2 = simplifyTypedefCopyTokens(tok2, argStart, argEnd, location);

tok2->insertToken(")");
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, ")", location);
Token::createMutualLinks(tok2, tok3);

tok2 = TokenList::copyTokens(tok2, argFuncRetStart, argFuncRetEnd);
tok2 = simplifyTypedefCopyTokens(tok2, argFuncRetStart, argFuncRetEnd, location);
} else if (ptrToArray || refToArray) {
tok2->insertToken("(");
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, "(", location);
Token *tok3 = tok2;

if (ptrToArray)
tok2->insertToken("*");
tok2 = simplifyTypedefInsertToken(tok2, "*", location);
else
tok2->insertToken("&");
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, "&", location);

bool hasName = false;
// skip over name
Expand All @@ -2234,15 +2220,14 @@ void Tokenizer::simplifyTypedefCpp()
tok2 = tok2->linkAt(1);
}

tok2->insertToken(")");
simplifyTypedefInsertToken(tok2, ")", location);
Token::createMutualLinks(tok2->next(), tok3);

if (!hasName)
tok2 = tok2->next();
} else if (ptrMember) {
if (Token::simpleMatch(tok2, "* (")) {
tok2->insertToken("*");
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, "*", location);
} else {
// This is the case of casting operator.
// Name is not available, and () should not be
Expand All @@ -2251,38 +2236,33 @@ void Tokenizer::simplifyTypedefCpp()
Token *openParenthesis = nullptr;

if (!castOperator) {
tok2->insertToken("(");
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, "(", location);

openParenthesis = tok2;
}

const Token *tok4 = namespaceStart;

while (tok4 != namespaceEnd) {
tok2->insertToken(tok4->str());
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, tok4->str(), location);
tok4 = tok4->next();
}
tok2->insertToken(namespaceEnd->str());
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, namespaceEnd->str(), location);

tok2->insertToken("*");
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, "*", location);

if (openParenthesis) {
// Skip over name, if any
if (Token::Match(tok2->next(), "%name%"))
tok2 = tok2->next();

tok2->insertToken(")");
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, ")", location);

Token::createMutualLinks(tok2, openParenthesis);
}
}
} else if (typeOf) {
tok2 = TokenList::copyTokens(tok2, argStart, argEnd);
tok2 = simplifyTypedefCopyTokens(tok2, argStart, argEnd, location);
} else if (Token::Match(tok2, "%name% [")) {
while (Token::Match(tok2, "%name%|] [")) {
tok2 = tok2->linkAt(1);
Expand All @@ -2304,8 +2284,7 @@ void Tokenizer::simplifyTypedefCpp()
// reference or pointer to array?
if (Token::Match(tok2, "&|*|&&")) {
tok2 = tok2->previous();
tok2->insertToken("(");
Token *tok3 = tok2->next();
Token *tok3 = simplifyTypedefInsertToken(tok2, "(", location);

// handle missing variable name
if (Token::Match(tok3, "( *|&|&& *|&|&& %name%"))
Expand Down Expand Up @@ -2336,8 +2315,7 @@ void Tokenizer::simplifyTypedefCpp()
tok2 = tok2->tokAt(3);
}

tok2->insertToken(")");
tok2 = tok2->next();
tok2 = simplifyTypedefInsertToken(tok2, ")", location);
Token::createMutualLinks(tok2, tok3);
}

Expand All @@ -2348,7 +2326,7 @@ void Tokenizer::simplifyTypedefCpp()
while (tok2->strAt(1) == "[")
tok2 = tok2->linkAt(1);

tok2 = TokenList::copyTokens(tok2, arrayStart, arrayEnd);
tok2 = simplifyTypedefCopyTokens(tok2, arrayStart, arrayEnd, location);
if (!tok2->next())
syntaxError(tok2);

Expand Down
23 changes: 21 additions & 2 deletions test/testsimplifytypedef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,8 @@ class TestSimplifyTypedef : public TestFixture {

TEST_CASE(simplifyTypedefOriginalName);

TEST_CASE(simplifyTypedefTokenColumn);
TEST_CASE(simplifyTypedefTokenColumn1);
TEST_CASE(simplifyTypedefTokenColumn2);

TEST_CASE(typedefInfo1);

Expand Down Expand Up @@ -4456,7 +4457,7 @@ class TestSimplifyTypedef : public TestFixture {
ASSERT_EQUALS("rFunctionPointer_fp", token->originalName());
}

void simplifyTypedefTokenColumn() { // #13155
void simplifyTypedefTokenColumn1() { // #13155
const char code[] = "void foo(void) {\n"
" typedef signed int MY_INT;\n"
" MY_INT x = 0;\n"
Expand All @@ -4474,6 +4475,24 @@ class TestSimplifyTypedef : public TestFixture {
ASSERT_EQUALS(5, type->column());
}

void simplifyTypedefTokenColumn2() {
const char code[] = "void foo(void) {\n"
" typedef signed int (*F)(int);\n"
" F x = 0;\n"
"}";

Tokenizer tokenizer(settings1, *this);
std::istringstream istr(code);
ASSERT(tokenizer.list.createTokens(istr, "file.c"));
tokenizer.createLinks();
tokenizer.simplifyTypedef();

const Token* x = Token::findsimplematch(tokenizer.list.front(), "x");
const Token* type = x->previous();
ASSERT_EQUALS("*", type->str());
ASSERT_EQUALS(5, type->column());
}

void typedefInfo1() {
const std::string xml = dumpTypedefInfo("typedef int A;\nA x;");
ASSERT_EQUALS(" <typedef-info>\n"
Expand Down

0 comments on commit a6e65eb

Please sign in to comment.