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

View File

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

View File

@ -657,6 +657,11 @@ private:
*/ */
void simplifyAsm2(); void simplifyAsm2();
/**
* Simplify @..
*/
void simplifyAt();
/** /**
* Simplify bitfields - the field width is removed as we don't use it. * 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(simplifyCasts16); // #6278
TEST_CASE(simplifyCasts17); // #6110 - don't remove any parentheses in 'a(b)(c)' TEST_CASE(simplifyCasts17); // #6110 - don't remove any parentheses in 'a(b)(c)'
TEST_CASE(simplifyAt);
TEST_CASE(inlineasm); TEST_CASE(inlineasm);
TEST_CASE(simplifyAsm2); // #4725 (writing asm() around "^{}") TEST_CASE(simplifyAsm2); // #4725 (writing asm() around "^{}")
@ -1065,6 +1067,11 @@ private:
tokenizeAndStringify("if (a(b)(c) >= 3)", true)); 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() { void inlineasm() {
ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify("asm { mov ax,bx };")); ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify("asm { mov ax,bx };"));
ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify("_asm { mov ax,bx };")); ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify("_asm { mov ax,bx };"));