Skip to content

Commit cbbf018

Browse files
committed
Add tag line and column in typedef-info in dump file
1 parent a8f83c1 commit cbbf018

File tree

3 files changed

+100
-59
lines changed

3 files changed

+100
-59
lines changed

lib/tokenize.cpp

Lines changed: 85 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,6 +1104,10 @@ void Tokenizer::simplifyTypedef()
11041104
typedefInfo.filename = list.file(typedefToken);
11051105
typedefInfo.lineNumber = typedefToken->linenr();
11061106
typedefInfo.column = typedefToken->column();
1107+
if (Token::Match(typedefToken->next(), "struct|enum|class|union %name% {") && typedefToken->strAt(2) == typedefInfo.name) {
1108+
typedefInfo.tagLine = typedefToken->tokAt(2)->linenr();
1109+
typedefInfo.tagColumn = typedefToken->tokAt(2)->column();
1110+
}
11071111
typedefInfo.used = t.second.isUsed();
11081112
typedefInfo.isFunctionPointer = isFunctionPointer(t.second.nameToken());
11091113
if (typedefInfo.isFunctionPointer) {
@@ -1165,7 +1169,7 @@ void Tokenizer::simplifyTypedefCpp()
11651169
const std::time_t maxTime = mSettings.typedefMaxTime > 0 ? std::time(nullptr) + mSettings.typedefMaxTime: 0;
11661170
const bool doProgress = (mSettings.reportProgress != -1) && !list.getFiles().empty();
11671171

1168-
for (Token *tok = list.front(); tok; tok = tok->next()) {
1172+
for (Token* tok = list.front(); tok; tok = tok->next()) {
11691173
if (doProgress)
11701174
mErrorLogger.reportProgress(list.getFiles()[0], "Tokenize (typedef)", tok->progressValue());
11711175

@@ -1175,12 +1179,12 @@ void Tokenizer::simplifyTypedefCpp()
11751179
if (maxTime > 0 && std::time(nullptr) > maxTime) {
11761180
if (mSettings.debugwarnings) {
11771181
ErrorMessage::FileLocation loc(list.getFiles()[0], 0, 0);
1178-
ErrorMessage errmsg({std::move(loc)},
1179-
"",
1180-
Severity::debug,
1181-
"Typedef simplification instantiation maximum time exceeded",
1182-
"typedefMaxTime",
1183-
Certainty::normal);
1182+
ErrorMessage errmsg({ std::move(loc) },
1183+
"",
1184+
Severity::debug,
1185+
"Typedef simplification instantiation maximum time exceeded",
1186+
"typedefMaxTime",
1187+
Certainty::normal);
11841188
mErrorLogger.reportErr(errmsg);
11851189
}
11861190
return;
@@ -1196,20 +1200,23 @@ void Tokenizer::simplifyTypedefCpp()
11961200
if (Token::simpleMatch(tok, "( typedef")) {
11971201
// Skip typedefs inside parentheses (#2453 and #4002)
11981202
tok = tok->next();
1199-
} else if (Token::Match(tok, "class|struct|namespace %any%") &&
1200-
(!tok->previous() || tok->strAt(-1) != "enum")) {
1203+
}
1204+
else if (Token::Match(tok, "class|struct|namespace %any%") &&
1205+
(!tok->previous() || tok->strAt(-1) != "enum")) {
12011206
isNamespace = (tok->str() == "namespace");
12021207
hasClass = true;
12031208
className = tok->strAt(1);
1204-
const Token *tok1 = tok->next();
1209+
const Token* tok1 = tok->next();
12051210
fullClassName = className;
12061211
while (Token::Match(tok1, "%name% :: %name%")) {
12071212
tok1 = tok1->tokAt(2);
12081213
fullClassName += " :: " + tok1->str();
12091214
}
1210-
} else if (hasClass && tok->str() == ";") {
1215+
}
1216+
else if (hasClass && tok->str() == ";") {
12111217
hasClass = false;
1212-
} else if (hasClass && tok->str() == "{") {
1218+
}
1219+
else if (hasClass && tok->str() == "{") {
12131220
if (!isNamespace)
12141221
spaceInfo.back().recordTypes.insert(fullClassName);
12151222

@@ -1221,7 +1228,8 @@ void Tokenizer::simplifyTypedefCpp()
12211228
spaceInfo.push_back(std::move(info));
12221229

12231230
hasClass = false;
1224-
} else if (spaceInfo.size() > 1 && tok->str() == "}" && spaceInfo.back().bodyEnd == tok) {
1231+
}
1232+
else if (spaceInfo.size() > 1 && tok->str() == "}" && spaceInfo.back().bodyEnd == tok) {
12251233
spaceInfo.pop_back();
12261234
}
12271235
continue;
@@ -1233,7 +1241,7 @@ void Tokenizer::simplifyTypedefCpp()
12331241
while (Token::Match(tokClass, "const|volatile"))
12341242
tokClass = tokClass->next();
12351243
if (Token::Match(tokClass, "struct|enum|union|class %type%| {|:")) {
1236-
Token *tok1 = splitDefinitionFromTypedef(tok, &mUnnamedCount);
1244+
Token* tok1 = splitDefinitionFromTypedef(tok, &mUnnamedCount);
12371245
if (!tok1)
12381246
continue;
12391247
tok = tok1;
@@ -1250,21 +1258,21 @@ void Tokenizer::simplifyTypedefCpp()
12501258
continue;
12511259
}
12521260

1253-
Token *typeName;
1254-
Token *typeStart = nullptr;
1255-
Token *typeEnd = nullptr;
1256-
Token *argStart = nullptr;
1257-
Token *argEnd = nullptr;
1258-
Token *arrayStart = nullptr;
1259-
Token *arrayEnd = nullptr;
1260-
Token *specStart = nullptr;
1261-
Token *specEnd = nullptr;
1262-
Token *typeDef = tok;
1263-
Token *argFuncRetStart = nullptr;
1264-
Token *argFuncRetEnd = nullptr;
1265-
Token *funcStart = nullptr;
1266-
Token *funcEnd = nullptr;
1267-
Token *tokOffset = tok->next();
1261+
Token* typeName;
1262+
Token* typeStart = nullptr;
1263+
Token* typeEnd = nullptr;
1264+
Token* argStart = nullptr;
1265+
Token* argEnd = nullptr;
1266+
Token* arrayStart = nullptr;
1267+
Token* arrayEnd = nullptr;
1268+
Token* specStart = nullptr;
1269+
Token* specEnd = nullptr;
1270+
Token* typeDef = tok;
1271+
Token* argFuncRetStart = nullptr;
1272+
Token* argFuncRetEnd = nullptr;
1273+
Token* funcStart = nullptr;
1274+
Token* funcEnd = nullptr;
1275+
Token* tokOffset = tok->next();
12681276
bool function = false;
12691277
bool functionPtr = false;
12701278
bool functionRetFuncPtr = false;
@@ -1273,8 +1281,8 @@ void Tokenizer::simplifyTypedefCpp()
12731281
bool refToArray = false;
12741282
bool ptrMember = false;
12751283
bool typeOf = false;
1276-
const Token *namespaceStart = nullptr;
1277-
Token *namespaceEnd = nullptr;
1284+
const Token* namespaceStart = nullptr;
1285+
Token* namespaceEnd = nullptr;
12781286

12791287
// check for invalid input
12801288
if (!tokOffset || tokOffset->isControlFlowKeyword())
@@ -1291,7 +1299,8 @@ void Tokenizer::simplifyTypedefCpp()
12911299

12921300
if (Token::Match(tokOffset, "%type%"))
12931301
tokOffset = tokOffset->next();
1294-
} else if (Token::Match(tokOffset, "%type% ::")) {
1302+
}
1303+
else if (Token::Match(tokOffset, "%type% ::")) {
12951304
typeStart = tokOffset;
12961305

12971306
do {
@@ -1302,20 +1311,21 @@ void Tokenizer::simplifyTypedefCpp()
13021311

13031312
if (Token::Match(tokOffset, "%type%"))
13041313
tokOffset = tokOffset->next();
1305-
} else if (Token::Match(tokOffset, "%type%")) {
1314+
}
1315+
else if (Token::Match(tokOffset, "%type%")) {
13061316
typeStart = tokOffset;
13071317

13081318
while (Token::Match(tokOffset, "const|struct|enum %type%") ||
1309-
(tokOffset->next() && tokOffset->next()->isStandardType() && !Token::Match(tokOffset->next(), "%name% ;")))
1319+
(tokOffset->next() && tokOffset->next()->isStandardType() && !Token::Match(tokOffset->next(), "%name% ;")))
13101320
tokOffset = tokOffset->next();
13111321

13121322
typeEnd = tokOffset;
13131323
if (!Token::Match(tokOffset->next(), "%name% ;"))
13141324
tokOffset = tokOffset->next();
13151325

13161326
while (Token::Match(tokOffset, "%type%") &&
1317-
(tokOffset->isStandardType() || Token::Match(tokOffset, "unsigned|signed")) &&
1318-
!Token::Match(tokOffset->next(), "%name% ;")) {
1327+
(tokOffset->isStandardType() || Token::Match(tokOffset, "unsigned|signed")) &&
1328+
!Token::Match(tokOffset->next(), "%name% ;")) {
13191329
typeEnd = tokOffset;
13201330
tokOffset = tokOffset->next();
13211331
}
@@ -1331,14 +1341,17 @@ void Tokenizer::simplifyTypedefCpp()
13311341
tokOffset->next() && !Token::Match(tokOffset->next(), "[|;|,|(")) {
13321342
typeEnd = tokOffset;
13331343
tokOffset = tokOffset->next();
1334-
} else if (Token::simpleMatch(tokOffset, "const (")) {
1344+
}
1345+
else if (Token::simpleMatch(tokOffset, "const (")) {
13351346
typeEnd = tokOffset;
13361347
tokOffset = tokOffset->next();
13371348
atEnd = true;
1338-
} else
1349+
}
1350+
else
13391351
atEnd = true;
13401352
}
1341-
} else
1353+
}
1354+
else
13421355
continue; // invalid input
13431356

13441357
// check for invalid input
@@ -1394,7 +1407,7 @@ void Tokenizer::simplifyTypedefCpp()
13941407

13951408
// or a function typedef
13961409
else if (tokOffset && tokOffset->str() == "(") {
1397-
Token *tokOffset2 = nullptr;
1410+
Token* tokOffset2 = nullptr;
13981411
if (Token::Match(tokOffset, "( *|%name%")) {
13991412
tokOffset2 = tokOffset->next();
14001413
if (tokOffset2->str() == "typename")
@@ -1458,7 +1471,7 @@ void Tokenizer::simplifyTypedefCpp()
14581471

14591472
// typeof: typedef typeof ( ... ) type;
14601473
else if (Token::simpleMatch(tokOffset->previous(), "typeof (") &&
1461-
Token::Match(tokOffset->link(), ") %type% ;")) {
1474+
Token::Match(tokOffset->link(), ") %type% ;")) {
14621475
argStart = tokOffset;
14631476
argEnd = tokOffset->link();
14641477
typeName = tokOffset->link()->next();
@@ -1470,14 +1483,14 @@ void Tokenizer::simplifyTypedefCpp()
14701483
// typedef ... (( ... type )( ... ));
14711484
// typedef ... ( * ( ... type )( ... ));
14721485
else if (tokOffset->str() == "(" && (
1473-
(tokOffset->link() && Token::Match(tokOffset->link()->previous(), "%type% ) (") &&
1474-
Token::Match(tokOffset->link()->linkAt(1), ") const|volatile|;")) ||
1475-
(Token::simpleMatch(tokOffset, "( (") &&
1476-
tokOffset->next() && Token::Match(tokOffset->linkAt(1)->previous(), "%type% ) (") &&
1477-
Token::Match(tokOffset->linkAt(1)->linkAt(1), ") const|volatile| ) ;|,")) ||
1478-
(Token::simpleMatch(tokOffset, "( * (") &&
1479-
tokOffset->linkAt(2) && Token::Match(tokOffset->linkAt(2)->previous(), "%type% ) (") &&
1480-
Token::Match(tokOffset->linkAt(2)->linkAt(1), ") const|volatile| ) ;|,")))) {
1486+
(tokOffset->link() && Token::Match(tokOffset->link()->previous(), "%type% ) (") &&
1487+
Token::Match(tokOffset->link()->linkAt(1), ") const|volatile|;")) ||
1488+
(Token::simpleMatch(tokOffset, "( (") &&
1489+
tokOffset->next() && Token::Match(tokOffset->linkAt(1)->previous(), "%type% ) (") &&
1490+
Token::Match(tokOffset->linkAt(1)->linkAt(1), ") const|volatile| ) ;|,")) ||
1491+
(Token::simpleMatch(tokOffset, "( * (") &&
1492+
tokOffset->linkAt(2) && Token::Match(tokOffset->linkAt(2)->previous(), "%type% ) (") &&
1493+
Token::Match(tokOffset->linkAt(2)->linkAt(1), ") const|volatile| ) ;|,")))) {
14811494
if (tokOffset->strAt(1) == "(")
14821495
tokOffset = tokOffset->next();
14831496
else if (Token::simpleMatch(tokOffset, "( * (")) {
@@ -1504,7 +1517,7 @@ void Tokenizer::simplifyTypedefCpp()
15041517
syntaxError(tok2);
15051518

15061519
tok = argEnd->next();
1507-
Token *spec = tok;
1520+
Token* spec = tok;
15081521
if (Token::Match(spec, "const|volatile")) {
15091522
specStart = spec;
15101523
specEnd = spec;
@@ -1529,16 +1542,17 @@ void Tokenizer::simplifyTypedefCpp()
15291542
typeName = tokOffset->previous();
15301543
argStart = tokOffset;
15311544
argEnd = tokOffset->link();
1532-
} else {
1545+
}
1546+
else {
15331547
// internal error
15341548
continue;
15351549
}
15361550
}
15371551

15381552
// pointer to function returning pointer to function
15391553
else if (Token::Match(tokOffset, "( * ( * %type% ) (") &&
1540-
Token::simpleMatch(tokOffset->linkAt(6), ") ) (") &&
1541-
Token::Match(tokOffset->linkAt(6)->linkAt(2), ") ;|,")) {
1554+
Token::simpleMatch(tokOffset->linkAt(6), ") ) (") &&
1555+
Token::Match(tokOffset->linkAt(6)->linkAt(2), ") ;|,")) {
15421556
functionPtrRetFuncPtr = true;
15431557

15441558
tokOffset = tokOffset->tokAt(6);
@@ -1558,8 +1572,8 @@ void Tokenizer::simplifyTypedefCpp()
15581572

15591573
// function returning pointer to function
15601574
else if (Token::Match(tokOffset, "( * %type% (") &&
1561-
Token::simpleMatch(tokOffset->linkAt(3), ") ) (") &&
1562-
Token::Match(tokOffset->linkAt(3)->linkAt(2), ") ;|,")) {
1575+
Token::simpleMatch(tokOffset->linkAt(3), ") ) (") &&
1576+
Token::Match(tokOffset->linkAt(3)->linkAt(2), ") ;|,")) {
15631577
functionRetFuncPtr = true;
15641578

15651579
tokOffset = tokOffset->tokAt(3);
@@ -1576,7 +1590,8 @@ void Tokenizer::simplifyTypedefCpp()
15761590
syntaxError(tokOffset);
15771591

15781592
tok = argFuncRetEnd->next();
1579-
} else if (Token::Match(tokOffset, "( * ( %type% ) (")) {
1593+
}
1594+
else if (Token::Match(tokOffset, "( * ( %type% ) (")) {
15801595
functionRetFuncPtr = true;
15811596

15821597
tokOffset = tokOffset->tokAt(5);
@@ -1638,8 +1653,12 @@ void Tokenizer::simplifyTypedefCpp()
16381653
TypedefInfo typedefInfo;
16391654
typedefInfo.name = typeName->str();
16401655
typedefInfo.filename = list.file(typeName);
1641-
typedefInfo.lineNumber = typeName->linenr();
1642-
typedefInfo.column = typeName->column();
1656+
typedefInfo.lineNumber = typeDef->linenr();
1657+
typedefInfo.column = typeDef->column();
1658+
if (Token::Match(typeDef->next(), "struct|enum|class|union %name% {") && typeDef->strAt(2) == typedefInfo.name) {
1659+
typedefInfo.tagLine = typeDef->tokAt(2)->linenr();
1660+
typedefInfo.tagColumn = typeDef->tokAt(2)->column();
1661+
}
16431662
typedefInfo.used = false;
16441663
typedefInfo.isFunctionPointer = isFunctionPointer(typeName);
16451664
if (typedefInfo.isFunctionPointer) {
@@ -6326,7 +6345,15 @@ std::string Tokenizer::dumpTypedefInfo() const
63266345
outs += " column=\"";
63276346
outs += std::to_string(typedefInfo.column);
63286347
outs += "\"";
6348+
if (typedefInfo.tagLine > -1 && typedefInfo.tagColumn > -1) {
6349+
outs += " tagline=\"";
6350+
outs += std::to_string(typedefInfo.tagLine);
6351+
outs += "\"";
63296352

6353+
outs += " tagcolumn=\"";
6354+
outs += std::to_string(typedefInfo.tagColumn);
6355+
outs += "\"";
6356+
}
63306357
outs += " used=\"";
63316358
outs += std::to_string(typedefInfo.used?1:0);
63326359
outs += "\"";

lib/tokenize.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,8 @@ class CPPCHECKLIB Tokenizer {
696696
std::string filename;
697697
int lineNumber;
698698
int column;
699+
int tagLine{-1};
700+
int tagColumn{-1};
699701
bool used;
700702
bool isFunctionPointer;
701703
std::vector<TypedefToken> typedefInfoTokens;

test/testsimplifytypedef.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ class TestSimplifyTypedef : public TestFixture {
259259
TEST_CASE(typedefInfo1);
260260
TEST_CASE(typedefInfo2);
261261
TEST_CASE(typedefInfo3);
262+
TEST_CASE(typedefInfo4);
262263
}
263264

264265
class TokenizerTest : public Tokenizer
@@ -4609,7 +4610,7 @@ class TestSimplifyTypedef : public TestFixture {
46094610
" <token line=\"2\" column=\"35\" str=\")\"/>\n"
46104611
" </info>\n"
46114612
" <info name=\"int16_t\" file=\"file.c\" line=\"1\" column=\"1\" used=\"1\" isFunctionPointer=\"0\"/>\n"
4612-
" <info name=\"pfp16\" file=\"file.c\" line=\"4\" column=\"20\" used=\"0\" isFunctionPointer=\"1\">\n"
4613+
" <info name=\"pfp16\" file=\"file.c\" line=\"4\" column=\"4\" used=\"0\" isFunctionPointer=\"1\">\n"
46134614
" <token line=\"4\" column=\"4\" str=\"typedef\"/>\n"
46144615
" <token line=\"4\" column=\"12\" str=\"void\"/>\n"
46154616
" <token line=\"4\" column=\"12\" str=\"(\"/>\n"
@@ -4638,6 +4639,17 @@ class TestSimplifyTypedef : public TestFixture {
46384639
"}\n");
46394640
ASSERT_EQUALS("",xml);
46404641
}
4642+
4643+
void typedefInfo4() {
4644+
const std::string xml = dumpTypedefInfo("typedef struct coord {\n"
4645+
" uint16_t x;\n"
4646+
" uint16_t y;\n"
4647+
"} coord;\n"
4648+
"coord c;");
4649+
ASSERT_EQUALS(" <typedef-info>\n"
4650+
" <info name=\"coord\" file=\"file.c\" line=\"1\" column=\"1\" tagline=\"1\" tagcolumn=\"16\" used=\"1\" isFunctionPointer=\"0\"/>\n"
4651+
" </typedef-info>\n", xml);
4652+
}
46414653
};
46424654

46434655
REGISTER_TEST(TestSimplifyTypedef)

0 commit comments

Comments
 (0)