Fixed #9977 (Template simplifier does not simplify in header)
This commit is contained in:
parent
7182da5c8e
commit
c95b0d2a51
|
@ -5018,9 +5018,6 @@ void Tokenizer::dump(std::ostream &out) const
|
||||||
|
|
||||||
void Tokenizer::simplifyHeaders()
|
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->checkUnusedTemplates)
|
if (mSettings->checkHeaders && mSettings->checkUnusedTemplates)
|
||||||
// Full analysis. All information in the headers are kept.
|
// Full analysis. All information in the headers are kept.
|
||||||
return;
|
return;
|
||||||
|
@ -5031,11 +5028,16 @@ void Tokenizer::simplifyHeaders()
|
||||||
const bool removeUnusedIncludedTemplates = !mSettings->checkUnusedTemplates || !mSettings->checkHeaders;
|
const bool removeUnusedIncludedTemplates = !mSettings->checkUnusedTemplates || !mSettings->checkHeaders;
|
||||||
const bool removeUnusedTemplates = !mSettings->checkUnusedTemplates;
|
const bool removeUnusedTemplates = !mSettings->checkUnusedTemplates;
|
||||||
|
|
||||||
// We want to remove selected stuff from the headers but not *everything*.
|
// checkHeaders:
|
||||||
// The intention here is to not damage the analysis of the source file.
|
//
|
||||||
// You should get all warnings in the source file.
|
// If it is true then keep all code in the headers. It's possible
|
||||||
|
// to remove unused types/variables if false positives / false
|
||||||
// TODO: Remove unused types/variables/etc in headers..
|
// negatives can be avoided.
|
||||||
|
//
|
||||||
|
// If it is false, then 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. You should get all warnings in
|
||||||
|
// the source file. You should not get false positives.
|
||||||
|
|
||||||
// functions and types to keep
|
// functions and types to keep
|
||||||
std::set<std::string> keep;
|
std::set<std::string> keep;
|
||||||
|
@ -5043,7 +5045,7 @@ void Tokenizer::simplifyHeaders()
|
||||||
if (!tok->isName())
|
if (!tok->isName())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (checkHeaders && tok->fileIndex() != 0)
|
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), ") {")) {
|
||||||
|
|
|
@ -505,6 +505,8 @@ private:
|
||||||
TEST_CASE(unknownMacroBeforeReturn);
|
TEST_CASE(unknownMacroBeforeReturn);
|
||||||
|
|
||||||
TEST_CASE(cppcast);
|
TEST_CASE(cppcast);
|
||||||
|
|
||||||
|
TEST_CASE(checkHeader1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tokenizeAndStringify(const char code[], bool simplify = false, bool expand = true, Settings::PlatformType platform = Settings::Native, const char* filename = "test.cpp", bool cpp11 = true) {
|
std::string tokenizeAndStringify(const char code[], bool simplify = false, bool expand = true, Settings::PlatformType platform = Settings::Native, const char* filename = "test.cpp", bool cpp11 = true) {
|
||||||
|
@ -8601,6 +8603,60 @@ private:
|
||||||
ASSERT_EQUALS(tok->str() == "(", tok->isCast());
|
ASSERT_EQUALS(tok->str() == "(", tok->isCast());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string checkHeaders(const char code[], bool f) {
|
||||||
|
// Clear the error buffer..
|
||||||
|
errout.str("");
|
||||||
|
|
||||||
|
Settings settings;
|
||||||
|
settings.checkHeaders = f;
|
||||||
|
|
||||||
|
// Raw tokens..
|
||||||
|
std::vector<std::string> files(1, "test.cpp");
|
||||||
|
std::istringstream istr(code);
|
||||||
|
const simplecpp::TokenList tokens1(istr, files, files[0]);
|
||||||
|
|
||||||
|
// Preprocess..
|
||||||
|
simplecpp::TokenList tokens2(files);
|
||||||
|
std::map<std::string, simplecpp::TokenList*> filedata;
|
||||||
|
simplecpp::preprocess(tokens2, tokens1, files, filedata, simplecpp::DUI());
|
||||||
|
|
||||||
|
Preprocessor preprocessor(settings0, nullptr);
|
||||||
|
preprocessor.setDirectives(tokens1);
|
||||||
|
|
||||||
|
// Tokenizer..
|
||||||
|
Tokenizer tokenizer(&settings0, this);
|
||||||
|
tokenizer.createTokens(std::move(tokens2));
|
||||||
|
tokenizer.simplifyTokens1("");
|
||||||
|
|
||||||
|
return tokenizer.tokens()->stringifyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkHeader1() {
|
||||||
|
// #9977
|
||||||
|
const char code[] = "# 1 \"test.h\"\n"
|
||||||
|
"struct A {\n"
|
||||||
|
" int a = 1;\n"
|
||||||
|
" void f() { g(1); }\n"
|
||||||
|
" template <typename T> void g(T x) { a = 2; }\n" // <- template is used and should be kept
|
||||||
|
"};";
|
||||||
|
|
||||||
|
ASSERT_EQUALS("\n\n##file 1\n"
|
||||||
|
"1: struct A {\n"
|
||||||
|
"2: int a ; a = 1 ;\n"
|
||||||
|
"3: void f ( ) { g<int> ( 1 ) ; }\n"
|
||||||
|
"4: void g<int> ( int x ) ;\n"
|
||||||
|
"5: } ; void A :: g<int> ( int x ) { a = 2 ; }\n",
|
||||||
|
checkHeaders(code, true));
|
||||||
|
|
||||||
|
ASSERT_EQUALS("\n\n##file 1\n"
|
||||||
|
"1: struct A {\n"
|
||||||
|
"2: int a ; a = 1 ;\n"
|
||||||
|
"3: void f ( ) { g<int> ( 1 ) ; }\n"
|
||||||
|
"4: void g<int> ( int x ) ;\n"
|
||||||
|
"5: } ; void A :: g<int> ( int x ) { a = 2 ; }\n",
|
||||||
|
checkHeaders(code, false));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_TEST(TestTokenizer)
|
REGISTER_TEST(TestTokenizer)
|
||||||
|
|
Loading…
Reference in New Issue