- 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:
parent
cfcc0c82cc
commit
38ddcde7b0
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
|
114
lib/tokenize.cpp
114
lib/tokenize.cpp
|
@ -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()) {
|
||||
bool validSyntax = validSyntax = linkBrackets(this, type, links1, token, '{', '}');
|
||||
if (!validSyntax)
|
||||
return false;
|
||||
|
||||
validSyntax = linkBrackets(this, type, links2, token, '(', ')');
|
||||
if (!validSyntax)
|
||||
return false;
|
||||
|
||||
validSyntax = linkBrackets(this, type, links3, token, '[', ']');
|
||||
if (!validSyntax)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!links1.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(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();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
if (!links.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();
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue