Attempt to speed up preprocessing on macro-in-macro situations.
See #762 (version 1.37 of cppcheck runs extremely slowly on windows) http://sourceforge.net/apps/trac/cppcheck/ticket/762
This commit is contained in:
parent
107895e8cc
commit
70e236bc56
|
@ -1276,14 +1276,15 @@ public:
|
||||||
* To avoid name collisions, we will rename macro variables by
|
* To avoid name collisions, we will rename macro variables by
|
||||||
* adding _prefix in front of the name of each variable.
|
* adding _prefix in front of the name of each variable.
|
||||||
* Returns the macro with converted names
|
* Returns the macro with converted names
|
||||||
* @result If return value is false, this is not touched. If
|
* @param result If return value is false, this is not touched. If
|
||||||
* return value is true, this will contain new macro line
|
* return value is true, this will contain new macro line
|
||||||
* (all that comes after #define) e.g.
|
* (all that comes after #define) e.g.
|
||||||
* "A(__cppcheck__x) foo(__cppcheck__x);"
|
* "A(__cppcheck__x) foo(__cppcheck__x);"
|
||||||
|
* @param macro The macro which is about to cause name collision.
|
||||||
* @return true if code needs to be changed, false is no changes
|
* @return true if code needs to be changed, false is no changes
|
||||||
* are required.
|
* are required.
|
||||||
*/
|
*/
|
||||||
bool renameMacroVariables(std::string &result)
|
bool renameMacroVariables(std::string &result, const PreprocessorMacro ¯o)
|
||||||
{
|
{
|
||||||
// No variables
|
// No variables
|
||||||
if (_params.size() == 0)
|
if (_params.size() == 0)
|
||||||
|
@ -1293,6 +1294,31 @@ public:
|
||||||
if (_params[0].compare(0, _prefix.length(), _prefix) == 0)
|
if (_params[0].compare(0, _prefix.length(), _prefix) == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Check does the macro contain tokens that have
|
||||||
|
// the same name as parameters in this macro.
|
||||||
|
const Token *tok = macro.tokens();
|
||||||
|
if (Token::Match(tok->next(), "("))
|
||||||
|
{
|
||||||
|
std::map<std::string, bool> paramMap;
|
||||||
|
for (unsigned int i = 0; i < _params.size(); ++i)
|
||||||
|
paramMap[_params[i]] = true;
|
||||||
|
|
||||||
|
bool collision = false;
|
||||||
|
tok = Token::findmatch(tok, ")", 0);
|
||||||
|
for (; tok; tok = tok->next())
|
||||||
|
{
|
||||||
|
if (paramMap.find(tok->str()) != paramMap.end())
|
||||||
|
{
|
||||||
|
// Name collision
|
||||||
|
collision = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!collision)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
result = "";
|
result = "";
|
||||||
result.append(_name);
|
result.append(_name);
|
||||||
result.append("(");
|
result.append("(");
|
||||||
|
@ -1602,7 +1628,7 @@ std::string Preprocessor::expandMacros(std::string code, const std::string &file
|
||||||
|
|
||||||
PreprocessorMacro tempMacro(code.substr(startOfLine, endOfLine - startOfLine));
|
PreprocessorMacro tempMacro(code.substr(startOfLine, endOfLine - startOfLine));
|
||||||
std::string tempMacroCode;
|
std::string tempMacroCode;
|
||||||
if (tempMacro.renameMacroVariables(tempMacroCode))
|
if (tempMacro.renameMacroVariables(tempMacroCode, macro))
|
||||||
{
|
{
|
||||||
// Change the macro and then start again from the start
|
// Change the macro and then start again from the start
|
||||||
// of the line, as code has changed.
|
// of the line, as code has changed.
|
||||||
|
|
Loading…
Reference in New Issue