- Refactorizations in preprocessor.cpp and tokenizer.cpp

- Bugfix: tok->stringify(tok) returns now "".
- Removed most of the inline-asm handling in preprocessor; improved the remaining handling of #asm/#endasm: Simplified to "asm(...);" statement
This commit is contained in:
PKEuS 2012-01-02 12:58:34 +01:00
parent cfcc0c82cc
commit 38ddcde7b0
4 changed files with 58 additions and 148 deletions

View File

@ -266,7 +266,7 @@ std::string Preprocessor::preprocessCleanupDirectives(const std::string &process
static bool hasbom(const std::string &str)
{
return bool(str.size() > 3 &&
return bool(str.size() >= 3 &&
static_cast<unsigned char>(str[0]) == 0xef &&
static_cast<unsigned char>(str[1]) == 0xbb &&
static_cast<unsigned char>(str[2]) == 0xbf);
@ -284,13 +284,13 @@ static int tolowerWrapper(int c)
static bool isFallThroughComment(std::string comment)
{
// convert comment to lower case without whitespace
std::transform(comment.begin(), comment.end(), comment.begin(), tolowerWrapper);
for (std::string::iterator i = comment.begin(); i != comment.end();) {
if (std::isspace(static_cast<unsigned char>(*i)))
i = comment.erase(i);
else
++i;
}
std::transform(comment.begin(), comment.end(), comment.begin(), tolowerWrapper);
return comment.find("fallthr") != std::string::npos ||
comment.find("fallsthr") != std::string::npos ||
@ -650,83 +650,16 @@ std::string Preprocessor::removeParentheses(const std::string &str)
}
static void _removeAsm(std::string &str, const std::string::size_type pos)
{
unsigned int newlines = 0;
bool instr = false;
int parlevel = 0;
std::string::size_type pos2 = pos + 1;
while (pos2 < str.length()) {
if (str[pos2] == '\"')
instr = !instr;
else if (str[pos2] == '\n')
++newlines;
else if (!instr) {
if (str[pos2] == '(')
++parlevel;
else if (str[pos2] == ')') {
if (parlevel <= 1)
break;
--parlevel;
}
}
++pos2;
}
str.erase(pos + 1, pos2 - pos);
str.insert(pos, std::string(newlines, '\n'));
}
void Preprocessor::removeAsm(std::string &str)
{
std::string::size_type pos = 0;
while ((pos = str.find("\nasm(", pos)) != std::string::npos) {
_removeAsm(str, pos++);
str.insert(pos, "asm()");
}
pos = 0;
while ((pos = str.find("\nasm (", pos)) != std::string::npos) {
_removeAsm(str, pos++);
str.insert(pos, "asm()");
}
pos = 0;
while ((pos = str.find("\nasm __volatile(", pos)) != std::string::npos)
_removeAsm(str, pos);
pos = 0;
while ((pos = str.find("\nasm __volatile (", pos)) != std::string::npos)
_removeAsm(str, pos);
pos = 0;
while ((pos = str.find("#asm\n", pos)) != std::string::npos) {
const std::string::size_type pos1 = pos;
++pos;
str.replace(pos, 4, "asm(");
if (pos1 > 0 && str[pos1-1] != '\n')
continue;
const std::string::size_type endpos = str.find("\n#endasm", pos1);
if (endpos != std::string::npos) {
if (endpos + 8U < str.size() && str[endpos+8U] != '\n')
break;
// Remove '#endasm'
str.erase(endpos+1, 7);
// Remove non-newline characters between pos1 and endpos
for (std::string::size_type p = endpos; p > pos1; --p) {
if (str[p] != '\n')
str.erase(p,1);
}
str.erase(pos1,1);
// Insert 'asm();' to make the checks bailout properly
str.insert(pos1, ";asm();");
std::string::size_type pos2 = str.find("#endasm", pos);
if (pos2 != std::string::npos) {
str.replace(pos2, 7, ");");
pos = pos2;
}
}
}

View File

@ -893,6 +893,9 @@ void Token::printOut(const char *title, const std::vector<std::string> &fileName
std::string Token::stringify(const Token* end) const
{
if (this == end)
return "";
std::ostringstream ret;
if (isUnsigned())

View File

@ -4019,86 +4019,68 @@ void Tokenizer::setVarId()
}
}
bool linkBrackets(Tokenizer* tokenizer, std::stack<const Token*>& type, std::stack<Token*>& links, Token* token, char open, char close)
{
if (token->str().back() == open) {
links.push(token);
type.push(token);
} else if (token->str().back() == close) {
if (links.empty()) {
// Error, { and } don't match.
tokenizer->syntaxError(token, open);
return false;
}
if (type.top()->str().back() != open) {
tokenizer->syntaxError(type.top(), type.top()->str()[0]);
return false;
}
type.pop();
Token::createMutualLinks(links.top(), token);
links.pop();
}
return(true);
}
bool Tokenizer::createLinks()
{
std::list<const Token*> type;
std::list<Token*> links;
std::list<Token*> links2;
std::list<Token*> links3;
std::stack<const Token*> type;
std::stack<Token*> links1;
std::stack<Token*> links2;
std::stack<Token*> links3;
for (Token *token = _tokens; token; token = token->next()) {
if (token->link()) {
token->link(0);
}
if (token->str() == "{") {
links.push_back(token);
type.push_back(token);
} else if (token->str() == "}") {
if (links.empty()) {
// Error, { and } don't match.
syntaxError(token, '{');
return false;
}
if (type.back()->str() != "{") {
syntaxError(type.back(), type.back()->str()[0]);
return false;
}
type.pop_back();
bool validSyntax = validSyntax = linkBrackets(this, type, links1, token, '{', '}');
if (!validSyntax)
return false;
Token::createMutualLinks(links.back(), token);
links.pop_back();
} else if (token->str() == "(") {
links2.push_back(token);
type.push_back(token);
} else if (token->str() == ")") {
if (links2.empty()) {
// Error, ( and ) don't match.
syntaxError(token, '(');
return false;
}
if (type.back()->str() != "(") {
syntaxError(type.back(), type.back()->str()[0]);
return false;
}
type.pop_back();
validSyntax = linkBrackets(this, type, links2, token, '(', ')');
if (!validSyntax)
return false;
Token::createMutualLinks(links2.back(), token);
links2.pop_back();
} else if (token->str() == "[") {
links3.push_back(token);
type.push_back(token);
} else if (token->str() == "]") {
if (links3.empty()) {
// Error, [ and ] don't match.
syntaxError(token, '[');
return false;
}
if (type.back()->str() != "[") {
syntaxError(type.back(), type.back()->str()[0]);
return false;
}
type.pop_back();
Token::createMutualLinks(links3.back(), token);
links3.pop_back();
}
validSyntax = linkBrackets(this, type, links3, token, '[', ']');
if (!validSyntax)
return false;
}
if (!links.empty()) {
if (!links1.empty()) {
// Error, { and } don't match.
syntaxError(links.back(), '{');
syntaxError(links1.top(), '{');
return false;
}
if (!links2.empty()) {
// Error, ( and ) don't match.
syntaxError(links2.back(), '(');
syntaxError(links2.top(), '(');
return false;
}
if (!links3.empty()) {
// Error, [ and ] don't match.
syntaxError(links3.back(), '[');
syntaxError(links3.top(), '[');
return false;
}
@ -4479,7 +4461,7 @@ bool Tokenizer::simplifyTokenList()
// simplify "x=realloc(y,0);" => "free(y); x=0;"..
// and "x = realloc (0, n);" => "x = malloc(n);"
for (Token *tok = _tokens; tok; tok = tok->next()) {
if (Token::Match(tok, "; %var% = realloc ( %var% , 0 ) ;")) {
if (Token::Match(tok, "[;{}:] %var% = realloc ( %var% , 0 ) ;")) {
const std::string varname(tok->next()->str());
const unsigned int varid(tok->next()->varId());
@ -4502,7 +4484,7 @@ bool Tokenizer::simplifyTokenList()
tok->insertToken("=");
tok->insertToken(varname);
tok->next()->varId(varid);
} else if (Token::Match(tok, "; %var% = realloc ( 0 , %num% ) ;")) {
} else if (Token::Match(tok, "[;{}:] %var% = realloc ( 0 , %num% ) ;")) {
tok = tok->tokAt(3);
// Change function name "realloc" to "malloc"
tok->str("malloc");
@ -9360,7 +9342,7 @@ void Tokenizer::simplifyStructDecl()
void Tokenizer::simplifyCallingConvention()
{
const char pattern[] = "__cdecl|__stdcall|__fastcall|__thiscall|__clrcall|__syscall|__pascal|__fortran|__far|__near|WINAPI|APIENTRY|CALLBACK";
static const char pattern[] = "__cdecl|__stdcall|__fastcall|__thiscall|__clrcall|__syscall|__pascal|__fortran|__far|__near|WINAPI|APIENTRY|CALLBACK";
for (Token *tok = _tokens; tok; tok = tok->next()) {
while (Token::Match(tok, pattern)) {
tok->deleteThis();
@ -9403,7 +9385,7 @@ void Tokenizer::simplifyAttribute()
// Remove "volatile", "inline", "register", and "restrict"
void Tokenizer::simplifyKeyword()
{
const char pattern[] = "volatile|inline|__inline|__forceinline|register|restrict|__restrict|__restrict__";
static const char pattern[] = "volatile|inline|__inline|__forceinline|register|restrict|__restrict|__restrict__";
for (Token *tok = _tokens; tok; tok = tok->next()) {
while (Token::Match(tok, pattern)) {
tok->deleteThis();

View File

@ -1549,21 +1549,13 @@ private:
}
void remove_asm() {
std::string str1("\nasm(\n\n\n);");
std::string str1("#asm\nmov ax,bx\n#endasm");
Preprocessor::removeAsm(str1);
ASSERT_EQUALS("\nasm()\n\n\n;", str1);
ASSERT_EQUALS("asm(\nmov ax,bx\n);", str1);
std::string str2("\nasm __volatile(\"\nlw iScale, 0x00(pScale)\n\", ());");
std::string str2("\n#asm\nmov ax,bx\n#endasm\n");
Preprocessor::removeAsm(str2);
ASSERT_EQUALS("\n\n\n;", str2);
std::string str3("#asm\nmov ax,bx\n#endasm");
Preprocessor::removeAsm(str3);
ASSERT_EQUALS(";asm();\n\n", str3);
std::string str4("\n#asm\nmov ax,bx\n#endasm\n");
Preprocessor::removeAsm(str4);
ASSERT_EQUALS("\n;asm();\n\n\n", str4);
ASSERT_EQUALS("\nasm(\nmov ax,bx\n);\n", str2);
}
void if_defined() {