Tokenizer: Add simplifyAt to handle some nonstandard code with @

This commit is contained in:
Daniel Marjamäki 2018-12-04 16:52:41 +01:00
parent 7ef8f60b07
commit 49413b7d4c
4 changed files with 44 additions and 8 deletions

View File

@ -448,6 +448,12 @@ public:
void isEnumType(const bool value) {
setFlag(fIsEnumType, value);
}
bool isAtAddress() const {
return getFlag(fAtAddress);
}
void isAtAddress(bool b) {
setFlag(fAtAddress, b);
}
bool isBitfield() const {
return mBits > 0;
@ -984,6 +990,7 @@ private:
fIsTemplateArg = (1 << 22),
fIsAttributeNodiscard = (1 << 23), // __attribute__ ((warn_unused_result)), [[nodiscard]]
fHasTemplateSimplifierPointer = (1 << 24), // used by template simplifier to indicate it has a pointer to this token
fAtAddress = (1 << 25), // @ 0x4000
};
unsigned int mFlags;

View File

@ -3807,6 +3807,20 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
// Put ^{} statements in asm()
simplifyAsm2();
// @..
simplifyAt();
// When the assembly code has been cleaned up, no @ is allowed
for (const Token *tok = list.front(); tok; tok = tok->next()) {
if (tok->str() == "(") {
tok = tok->link();
if (!tok)
syntaxError(nullptr);
} else if (tok->str() == "@") {
syntaxError(nullptr);
}
}
// Order keywords "static" and "const"
simplifyStaticConst();
@ -9367,15 +9381,18 @@ void Tokenizer::simplifyAsm2()
}
}
}
}
// When the assembly code has been cleaned up, no @ is allowed
for (const Token *tok = list.front(); tok; tok = tok->next()) {
if (tok->str() == "(") {
tok = tok->link();
if (!tok)
syntaxError(nullptr);
} else if (tok->str()[0] == '@') {
syntaxError(nullptr);
void Tokenizer::simplifyAt()
{
for (Token *tok = list.front(); tok; tok = tok->next()) {
if (Token::Match(tok, "%name% @ %num% ;")) {
tok->isAtAddress(true);
Token::eraseTokens(tok,tok->tokAt(3));
}
if (Token::Match(tok, "@ far|near|interrupt")) {
tok->str(tok->next()->str() + "@");
tok->deleteNext();
}
}
}

View File

@ -657,6 +657,11 @@ private:
*/
void simplifyAsm2();
/**
* Simplify @..
*/
void simplifyAt();
/**
* Simplify bitfields - the field width is removed as we don't use it.
*/

View File

@ -109,6 +109,8 @@ private:
TEST_CASE(simplifyCasts16); // #6278
TEST_CASE(simplifyCasts17); // #6110 - don't remove any parentheses in 'a(b)(c)'
TEST_CASE(simplifyAt);
TEST_CASE(inlineasm);
TEST_CASE(simplifyAsm2); // #4725 (writing asm() around "^{}")
@ -1065,6 +1067,11 @@ private:
tokenizeAndStringify("if (a(b)(c) >= 3)", true));
}
void simplifyAt() {
ASSERT_EQUALS("int x ;", tokenizeAndStringify("int x@123;"));
ASSERT_EQUALS("interrupt@ f ( ) { }", tokenizeAndStringify("@interrupt f() {}"));
}
void inlineasm() {
ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify("asm { mov ax,bx };"));
ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify("_asm { mov ax,bx };"));