From fda0f52424bd0394b95046e02987176669eb4591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Tue, 5 Mar 2019 14:57:37 +0100 Subject: [PATCH] Add --remove-unused-templates flag to remove all unused templates --- cli/cmdlineparser.cpp | 12 +++++++----- lib/settings.cpp | 1 + lib/settings.h | 3 +++ lib/tokenize.cpp | 15 +++++++-------- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 421b9c705..5161d48ad 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -155,9 +155,13 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) else if (std::strcmp(argv[i], "--dump") == 0) mSettings->dump = true; + // TODO: These options are about removing code. Instead of having lots of different options + // can we create one option that is customizable somehow. // --check-headers=no else if (std::strcmp(argv[i], "--check-headers=no") == 0) mSettings->checkHeaders = false; + else if (std::strcmp(argv[i], "--remove-unused-templates") == 0) + mSettings->removeUnusedTemplates = true; else if (std::strcmp(argv[i], "--remove-unused-included-templates") == 0) mSettings->removeUnusedIncludedTemplates = true; @@ -1077,12 +1081,10 @@ void CmdLineParser::printHelp() " using e.g. ~ for home folder does not work. It is\n" " currently only possible to apply the base paths to\n" " files that are on a lower level in the directory tree.\n" + " --remove-unused-templates\n" + " Remove unused templates.\n" " --remove-unused-included-templates\n" - " Remove unused templates in included files. This option\n" - " can be used to speed up the analysis. The analysis of a\n" - " template can be more accurate when it is instantiated and\n" - " therefore it can be a good idea to only analyse the\n" - " instantiated templates.\n" + " Remove unused templates in included files.\n" " --report-progress Report progress messages while checking a file.\n" #ifdef HAVE_RULES " --rule= Match regular expression.\n" diff --git a/lib/settings.cpp b/lib/settings.cpp index 1d7b5c38b..59d4a903c 100644 --- a/lib/settings.cpp +++ b/lib/settings.cpp @@ -51,6 +51,7 @@ Settings::Settings() reportProgress(false), checkHeaders(true), removeUnusedIncludedTemplates(false), + removeUnusedTemplates(false), checkConfiguration(false), checkLibrary(false) { diff --git a/lib/settings.h b/lib/settings.h index d83e3713b..b90b05a2d 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -290,6 +290,9 @@ public: * be turned off to save CPU */ bool checkHeaders; + /** Remove unused templates in all files */ + bool removeUnusedTemplates; + /** Remove unused included templates */ bool removeUnusedIncludedTemplates; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 93a5065bc..b804ad5ed 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -4256,13 +4256,14 @@ void Tokenizer::simplifyHeaders() // TODO : can we remove anything in headers here? Like unused declarations. // Maybe if --dump is used we want to have _everything_. - if (mSettings->checkHeaders && !mSettings->removeUnusedIncludedTemplates) + if (mSettings->checkHeaders && !mSettings->removeUnusedTemplates && !mSettings->removeUnusedIncludedTemplates) // Default=full analysis. All information in the headers are kept. return; const bool checkHeaders = mSettings->checkHeaders; const bool removeUnusedIncludedFunctions = mSettings->checkHeaders; const bool removeUnusedIncludedClasses = mSettings->checkHeaders; + const bool removeUnusedTemplates = mSettings->removeUnusedTemplates; const bool removeUnusedIncludedTemplates = mSettings->checkHeaders || mSettings->removeUnusedIncludedTemplates; // We want to remove selected stuff from the headers but not *everything*. @@ -4293,12 +4294,10 @@ void Tokenizer::simplifyHeaders() const std::set functionStart{"static", "const", "unsigned", "signed", "void", "bool", "char", "short", "int", "long", "float", "*"}; for (Token *tok = list.front(); tok; tok = tok->next()) { - if (tok->fileIndex() == 0) - // Keep all code in the source file - continue; + const bool isIncluded = (tok->fileIndex() != 0); // Remove executable code - if (mSettings->checkHeaders && tok->str() == "{") { + if (isIncluded && mSettings->checkHeaders && tok->str() == "{") { // TODO: We probably need to keep the executable code if this function is called from the source file. const Token *prev = tok->previous(); while (prev && prev->isName()) @@ -4313,7 +4312,7 @@ void Tokenizer::simplifyHeaders() if (Token::Match(tok, "[;{}]")) { // Remove unused function declarations - if (removeUnusedIncludedFunctions) { + if (isIncluded && removeUnusedIncludedFunctions) { while (1) { Token *start = tok->next(); while (start && functionStart.find(start->str()) != functionStart.end()) @@ -4325,7 +4324,7 @@ void Tokenizer::simplifyHeaders() } } - if (removeUnusedIncludedClasses) { + if (isIncluded && removeUnusedIncludedClasses) { if (Token::Match(tok, "[;{}] class|struct %name% [:{]") && keep.find(tok->strAt(2)) == keep.end()) { // Remove this class/struct const Token *endToken = tok->tokAt(3); @@ -4339,7 +4338,7 @@ void Tokenizer::simplifyHeaders() } } - if (removeUnusedIncludedTemplates) { + if (removeUnusedTemplates || (isIncluded && removeUnusedIncludedTemplates)) { if (Token::Match(tok->next(), "template < %name%")) { const Token *tok2 = tok->tokAt(3); while (Token::Match(tok2, "%name% %name% [,=>]")) {