Support sizeof in preprocessor directives
Applied "patch" provided by michaeln123 in #4071
This commit is contained in:
parent
43e01a2b1a
commit
f238f3fad5
|
@ -1436,6 +1436,7 @@ void Preprocessor::simplifyCondition(const std::map<std::string, std::string> &c
|
||||||
bool modified = true;
|
bool modified = true;
|
||||||
while (modified) {
|
while (modified) {
|
||||||
modified = false;
|
modified = false;
|
||||||
|
modified |= tokenizer.simplifySizeof();
|
||||||
modified |= tokenizer.simplifyCalculations();
|
modified |= tokenizer.simplifyCalculations();
|
||||||
modified |= tokenizer.simplifyRedundantParenthesis();
|
modified |= tokenizer.simplifyRedundantParenthesis();
|
||||||
for (Token *tok = const_cast<Token *>(tokenizer.tokens()); tok; tok = tok->next()) {
|
for (Token *tok = const_cast<Token *>(tokenizer.tokens()); tok; tok = tok->next()) {
|
||||||
|
|
|
@ -3012,7 +3012,7 @@ void Tokenizer::createLinks2()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tokenizer::simplifySizeof()
|
bool Tokenizer::simplifySizeof()
|
||||||
{
|
{
|
||||||
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
||||||
if (Token::Match(tok, "class|struct %var%")) {
|
if (Token::Match(tok, "class|struct %var%")) {
|
||||||
|
@ -3069,6 +3069,7 @@ void Tokenizer::simplifySizeof()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ret = false;
|
||||||
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
||||||
if (tok->str() != "sizeof")
|
if (tok->str() != "sizeof")
|
||||||
continue;
|
continue;
|
||||||
|
@ -3089,6 +3090,7 @@ void Tokenizer::simplifySizeof()
|
||||||
std::ostringstream sz;
|
std::ostringstream sz;
|
||||||
sz << sizeof 'x';
|
sz << sizeof 'x';
|
||||||
tok->str(sz.str());
|
tok->str(sz.str());
|
||||||
|
ret = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3100,6 +3102,7 @@ void Tokenizer::simplifySizeof()
|
||||||
std::ostringstream sz;
|
std::ostringstream sz;
|
||||||
sz << sizeof 'x';
|
sz << sizeof 'x';
|
||||||
tok->str(sz.str());
|
tok->str(sz.str());
|
||||||
|
ret = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3109,6 +3112,7 @@ void Tokenizer::simplifySizeof()
|
||||||
std::ostringstream ostr;
|
std::ostringstream ostr;
|
||||||
ostr << (Token::getStrLength(tok) + 1);
|
ostr << (Token::getStrLength(tok) + 1);
|
||||||
tok->str(ostr.str());
|
tok->str(ostr.str());
|
||||||
|
ret = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3120,6 +3124,7 @@ void Tokenizer::simplifySizeof()
|
||||||
std::ostringstream ostr;
|
std::ostringstream ostr;
|
||||||
ostr << (Token::getStrLength(tok) + 1);
|
ostr << (Token::getStrLength(tok) + 1);
|
||||||
tok->str(ostr.str());
|
tok->str(ostr.str());
|
||||||
|
ret = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3192,6 +3197,7 @@ void Tokenizer::simplifySizeof()
|
||||||
if (Token::simpleMatch(tok->next(), "( * )")) {
|
if (Token::simpleMatch(tok->next(), "( * )")) {
|
||||||
tok->str(MathLib::toString<unsigned long>(sizeOfType(tok->tokAt(2))));
|
tok->str(MathLib::toString<unsigned long>(sizeOfType(tok->tokAt(2))));
|
||||||
tok->deleteNext(3);
|
tok->deleteNext(3);
|
||||||
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sizeof( a )
|
// sizeof( a )
|
||||||
|
@ -3201,6 +3207,7 @@ void Tokenizer::simplifySizeof()
|
||||||
tok->deleteThis();
|
tok->deleteThis();
|
||||||
tok->deleteNext();
|
tok->deleteNext();
|
||||||
tok->str(sizeOfVar[tok->varId()]);
|
tok->str(sizeOfVar[tok->varId()]);
|
||||||
|
ret = true;
|
||||||
} else {
|
} else {
|
||||||
// don't try to replace size of variable if variable has
|
// don't try to replace size of variable if variable has
|
||||||
// similar name with type (#329)
|
// similar name with type (#329)
|
||||||
|
@ -3212,6 +3219,7 @@ void Tokenizer::simplifySizeof()
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
tok->str(MathLib::toString<unsigned int>(size));
|
tok->str(MathLib::toString<unsigned int>(size));
|
||||||
tok->deleteNext(3);
|
tok->deleteNext(3);
|
||||||
|
ret = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3240,10 +3248,11 @@ void Tokenizer::simplifySizeof()
|
||||||
if (sz > 0) {
|
if (sz > 0) {
|
||||||
tok->str(MathLib::toString<size_t>(sz));
|
tok->str(MathLib::toString<size_t>(sz));
|
||||||
Token::eraseTokens(tok, tok->next()->link()->next());
|
Token::eraseTokens(tok, tok->next()->link()->next());
|
||||||
|
ret = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Tokenizer::simplifyTokenList()
|
bool Tokenizer::simplifyTokenList()
|
||||||
|
|
|
@ -207,8 +207,10 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replace sizeof() to appropriate size.
|
* Replace sizeof() to appropriate size.
|
||||||
|
* @return true if modifications to token-list are done.
|
||||||
|
* false if no modifications are done.
|
||||||
*/
|
*/
|
||||||
void simplifySizeof();
|
bool simplifySizeof();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simplify variable declarations (split up)
|
* Simplify variable declarations (split up)
|
||||||
|
|
|
@ -275,6 +275,8 @@ private:
|
||||||
TEST_CASE(macroChar);
|
TEST_CASE(macroChar);
|
||||||
|
|
||||||
TEST_CASE(validateCfg);
|
TEST_CASE(validateCfg);
|
||||||
|
|
||||||
|
TEST_CASE(if_sizeof);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3608,6 +3610,22 @@ private:
|
||||||
ASSERT_EQUALS(true, preprocessor.validateCfg("#undef DEBUG", "DEBUG"));
|
ASSERT_EQUALS(true, preprocessor.validateCfg("#undef DEBUG", "DEBUG"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void if_sizeof() { // #4071
|
||||||
|
static const char* code = "#if sizeof(wchar_t) == 2\n"
|
||||||
|
"Fred & Wilma\n"
|
||||||
|
"#elif sizeof(wchar_t) == 4\n"
|
||||||
|
"Fred & Wilma\n"
|
||||||
|
"#else\n"
|
||||||
|
"#endif";
|
||||||
|
|
||||||
|
Settings settings;
|
||||||
|
Preprocessor preprocessor(&settings, this);
|
||||||
|
std::istringstream istr(code);
|
||||||
|
std::map<std::string, std::string> actual;
|
||||||
|
preprocessor.preprocess(istr, actual, "file.c");
|
||||||
|
|
||||||
|
ASSERT_EQUALS("\nFred & Wilma\n\n\n\n\n", actual[""]);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_TEST(TestPreprocessor)
|
REGISTER_TEST(TestPreprocessor)
|
||||||
|
|
Loading…
Reference in New Issue