Added --remove-unused-included-templates option
This commit is contained in:
parent
973ccda733
commit
3675318208
|
@ -158,6 +158,8 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
|
||||||
// --check-headers=no
|
// --check-headers=no
|
||||||
else if (std::strcmp(argv[i], "--check-headers=no") == 0)
|
else if (std::strcmp(argv[i], "--check-headers=no") == 0)
|
||||||
mSettings->checkHeaders = false;
|
mSettings->checkHeaders = false;
|
||||||
|
else if (std::strcmp(argv[i], "--remove-unused-included-templates") == 0)
|
||||||
|
mSettings->removeUnusedIncludedTemplates = true;
|
||||||
|
|
||||||
// max ctu depth
|
// max ctu depth
|
||||||
else if (std::strncmp(argv[i], "--max-ctu-depth=", 16) == 0)
|
else if (std::strncmp(argv[i], "--max-ctu-depth=", 16) == 0)
|
||||||
|
@ -1075,6 +1077,9 @@ void CmdLineParser::printHelp()
|
||||||
" using e.g. ~ for home folder does not work. It is\n"
|
" using e.g. ~ for home folder does not work. It is\n"
|
||||||
" currently only possible to apply the base paths to\n"
|
" currently only possible to apply the base paths to\n"
|
||||||
" files that are on a lower level in the directory tree.\n"
|
" files that are on a lower level in the directory tree.\n"
|
||||||
|
" --remove-unused-included-templates\n"
|
||||||
|
" Remove unused templates in included files. This option\n"
|
||||||
|
" can be used to speed up the analysis.\n"
|
||||||
" --report-progress Report progress messages while checking a file.\n"
|
" --report-progress Report progress messages while checking a file.\n"
|
||||||
#ifdef HAVE_RULES
|
#ifdef HAVE_RULES
|
||||||
" --rule=<rule> Match regular expression.\n"
|
" --rule=<rule> Match regular expression.\n"
|
||||||
|
|
|
@ -50,6 +50,7 @@ Settings::Settings()
|
||||||
enforcedLang(None),
|
enforcedLang(None),
|
||||||
reportProgress(false),
|
reportProgress(false),
|
||||||
checkHeaders(true),
|
checkHeaders(true),
|
||||||
|
removeUnusedIncludedTemplates(false),
|
||||||
checkConfiguration(false),
|
checkConfiguration(false),
|
||||||
checkLibrary(false)
|
checkLibrary(false)
|
||||||
{
|
{
|
||||||
|
|
|
@ -285,10 +285,14 @@ public:
|
||||||
/** Check for incomplete info in library files? */
|
/** Check for incomplete info in library files? */
|
||||||
bool checkLibrary;
|
bool checkLibrary;
|
||||||
|
|
||||||
/** Check code in the headers, this is on by default but can
|
/**
|
||||||
|
* Check code in the headers, this is on by default but can
|
||||||
* be turned off to save CPU */
|
* be turned off to save CPU */
|
||||||
bool checkHeaders;
|
bool checkHeaders;
|
||||||
|
|
||||||
|
/** Remove unused included templates */
|
||||||
|
bool removeUnusedIncludedTemplates;
|
||||||
|
|
||||||
/** Struct contains standards settings */
|
/** Struct contains standards settings */
|
||||||
Standards standards;
|
Standards standards;
|
||||||
|
|
||||||
|
|
|
@ -4256,10 +4256,15 @@ void Tokenizer::simplifyHeaders()
|
||||||
// TODO : can we remove anything in headers here? Like unused declarations.
|
// TODO : can we remove anything in headers here? Like unused declarations.
|
||||||
// Maybe if --dump is used we want to have _everything_.
|
// Maybe if --dump is used we want to have _everything_.
|
||||||
|
|
||||||
if (mSettings->checkHeaders)
|
if (mSettings->checkHeaders && !mSettings->removeUnusedIncludedTemplates)
|
||||||
// Default=full analysis. All information in the headers are kept.
|
// Default=full analysis. All information in the headers are kept.
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const bool checkHeaders = mSettings->checkHeaders;
|
||||||
|
const bool removeUnusedIncludedFunctions = mSettings->checkHeaders;
|
||||||
|
const bool removeUnusedIncludedClasses = mSettings->checkHeaders;
|
||||||
|
const bool removeUnusedIncludedTemplates = mSettings->checkHeaders || mSettings->removeUnusedIncludedTemplates;
|
||||||
|
|
||||||
// We want to remove selected stuff from the headers but not *everything*.
|
// We want to remove selected stuff from the headers but not *everything*.
|
||||||
// The intention here is to not damage the analysis of the source file.
|
// The intention here is to not damage the analysis of the source file.
|
||||||
// You should get all warnings in the source file.
|
// You should get all warnings in the source file.
|
||||||
|
@ -4269,7 +4274,10 @@ void Tokenizer::simplifyHeaders()
|
||||||
// functions and types to keep
|
// functions and types to keep
|
||||||
std::set<std::string> keep;
|
std::set<std::string> keep;
|
||||||
for (const Token *tok = list.front(); tok; tok = tok->next()) {
|
for (const Token *tok = list.front(); tok; tok = tok->next()) {
|
||||||
if (tok->fileIndex() != 0 || !tok->isName())
|
if (!tok->isName())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (checkHeaders && tok->fileIndex() != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (Token::Match(tok, "%name% (") && !Token::simpleMatch(tok->linkAt(1), ") {")) {
|
if (Token::Match(tok, "%name% (") && !Token::simpleMatch(tok->linkAt(1), ") {")) {
|
||||||
|
@ -4290,7 +4298,7 @@ void Tokenizer::simplifyHeaders()
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Remove executable code
|
// Remove executable code
|
||||||
if (tok->str() == "{") {
|
if (mSettings->checkHeaders && tok->str() == "{") {
|
||||||
// TODO: We probably need to keep the executable code if this function is called from the source file.
|
// TODO: We probably need to keep the executable code if this function is called from the source file.
|
||||||
const Token *prev = tok->previous();
|
const Token *prev = tok->previous();
|
||||||
while (prev && prev->isName())
|
while (prev && prev->isName())
|
||||||
|
@ -4305,48 +4313,54 @@ void Tokenizer::simplifyHeaders()
|
||||||
|
|
||||||
if (Token::Match(tok, "[;{}]")) {
|
if (Token::Match(tok, "[;{}]")) {
|
||||||
// Remove unused function declarations
|
// Remove unused function declarations
|
||||||
while (1) {
|
if (removeUnusedIncludedFunctions) {
|
||||||
Token *start = tok->next();
|
while (1) {
|
||||||
while (start && functionStart.find(start->str()) != functionStart.end())
|
Token *start = tok->next();
|
||||||
start = start->next();
|
while (start && functionStart.find(start->str()) != functionStart.end())
|
||||||
if (Token::Match(start, "%name% (") && Token::Match(start->linkAt(1), ") const| ;") && keep.find(start->str()) == keep.end())
|
start = start->next();
|
||||||
Token::eraseTokens(tok, start->linkAt(1)->tokAt(2));
|
if (Token::Match(start, "%name% (") && Token::Match(start->linkAt(1), ") const| ;") && keep.find(start->str()) == keep.end())
|
||||||
else
|
Token::eraseTokens(tok, start->linkAt(1)->tokAt(2));
|
||||||
break;
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Token::Match(tok, "[;{}] class|struct %name% [:{]") && keep.find(tok->strAt(2)) == keep.end()) {
|
if (removeUnusedIncludedClasses) {
|
||||||
// Remove this class/struct
|
if (Token::Match(tok, "[;{}] class|struct %name% [:{]") && keep.find(tok->strAt(2)) == keep.end()) {
|
||||||
const Token *endToken = tok->tokAt(3);
|
// Remove this class/struct
|
||||||
if (endToken->str() == ":") {
|
const Token *endToken = tok->tokAt(3);
|
||||||
endToken = endToken->next();
|
|
||||||
while (Token::Match(endToken, "%name%|,"))
|
|
||||||
endToken = endToken->next();
|
|
||||||
}
|
|
||||||
if (endToken && endToken->str() == "{" && Token::simpleMatch(endToken->link(), "} ;"))
|
|
||||||
Token::eraseTokens(tok, endToken->link()->next());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Token::Match(tok->next(), "template < %name%")) {
|
|
||||||
const Token *tok2 = tok->tokAt(3);
|
|
||||||
while (Token::Match(tok2, "%name% %name% [,=>]")) {
|
|
||||||
tok2 = tok2->tokAt(2);
|
|
||||||
if (Token::Match(tok2, "= %name% [,>]"))
|
|
||||||
tok2 = tok2->tokAt(2);
|
|
||||||
if (tok2->str() == ",")
|
|
||||||
tok2 = tok2->next();
|
|
||||||
}
|
|
||||||
if (Token::Match(tok2, "> class|struct %name% [;:{]") && keep.find(tok2->strAt(2)) == keep.end()) {
|
|
||||||
const Token *endToken = tok2->tokAt(3);
|
|
||||||
if (endToken->str() == ":") {
|
if (endToken->str() == ":") {
|
||||||
endToken = endToken->next();
|
endToken = endToken->next();
|
||||||
while (Token::Match(endToken, "%name%|,"))
|
while (Token::Match(endToken, "%name%|,"))
|
||||||
endToken = endToken->next();
|
endToken = endToken->next();
|
||||||
}
|
}
|
||||||
if (endToken && endToken->str() == "{")
|
if (endToken && endToken->str() == "{" && Token::simpleMatch(endToken->link(), "} ;"))
|
||||||
endToken = endToken->link()->next();
|
Token::eraseTokens(tok, endToken->link()->next());
|
||||||
if (endToken && endToken->str() == ";")
|
}
|
||||||
Token::eraseTokens(tok, endToken);
|
}
|
||||||
|
|
||||||
|
if (removeUnusedIncludedTemplates) {
|
||||||
|
if (Token::Match(tok->next(), "template < %name%")) {
|
||||||
|
const Token *tok2 = tok->tokAt(3);
|
||||||
|
while (Token::Match(tok2, "%name% %name% [,=>]")) {
|
||||||
|
tok2 = tok2->tokAt(2);
|
||||||
|
if (Token::Match(tok2, "= %name% [,>]"))
|
||||||
|
tok2 = tok2->tokAt(2);
|
||||||
|
if (tok2->str() == ",")
|
||||||
|
tok2 = tok2->next();
|
||||||
|
}
|
||||||
|
if (Token::Match(tok2, "> class|struct %name% [;:{]") && keep.find(tok2->strAt(2)) == keep.end()) {
|
||||||
|
const Token *endToken = tok2->tokAt(3);
|
||||||
|
if (endToken->str() == ":") {
|
||||||
|
endToken = endToken->next();
|
||||||
|
while (Token::Match(endToken, "%name%|,"))
|
||||||
|
endToken = endToken->next();
|
||||||
|
}
|
||||||
|
if (endToken && endToken->str() == "{")
|
||||||
|
endToken = endToken->link()->next();
|
||||||
|
if (endToken && endToken->str() == ";")
|
||||||
|
Token::eraseTokens(tok, endToken);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue