From a6e65ebc6ba22964e87d4aee0876c58ca4d7c33b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 1 Dec 2024 16:01:06 +0100 Subject: [PATCH] refactor, improve --- lib/tokenize.cpp | 156 +++++++++++++++-------------------- test/testsimplifytypedef.cpp | 23 +++++- 2 files changed, 88 insertions(+), 91 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 7ba4ab5957e..d059ee5727f 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -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() { @@ -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(); @@ -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); } } @@ -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(" ::"); @@ -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); @@ -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); } } } @@ -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) @@ -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 @@ -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 @@ -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 @@ -2251,8 +2236,7 @@ void Tokenizer::simplifyTypedefCpp() Token *openParenthesis = nullptr; if (!castOperator) { - tok2->insertToken("("); - tok2 = tok2->next(); + tok2 = simplifyTypedefInsertToken(tok2, "(", location); openParenthesis = tok2; } @@ -2260,29 +2244,25 @@ void Tokenizer::simplifyTypedefCpp() 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); @@ -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%")) @@ -2336,8 +2315,7 @@ void Tokenizer::simplifyTypedefCpp() tok2 = tok2->tokAt(3); } - tok2->insertToken(")"); - tok2 = tok2->next(); + tok2 = simplifyTypedefInsertToken(tok2, ")", location); Token::createMutualLinks(tok2, tok3); } @@ -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); diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index fca3b664151..c93233ca0e1 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -243,7 +243,8 @@ class TestSimplifyTypedef : public TestFixture { TEST_CASE(simplifyTypedefOriginalName); - TEST_CASE(simplifyTypedefTokenColumn); + TEST_CASE(simplifyTypedefTokenColumn1); + TEST_CASE(simplifyTypedefTokenColumn2); TEST_CASE(typedefInfo1); @@ -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" @@ -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(" \n"