C++: More flexibility for string representation of macros

It's now possible to get the macro definition with the actual
line breaks used on the code. This is particularly useful for
tooltips in order for them to look nice.

The preprocessor is changed so the macro also stores the breaks
positions. This doesn't seem to have any impact on performance.
In my machine, for example, the total time for parsing Creator's
source code is approx. 18100ms with or without the patch.

Change-Id: Ic7487236315c3567d26496315accdb2adfea894a
Reviewed-on: http://codereview.qt.nokia.com/4253
Reviewed-by: Christian Kamm <christian.d.kamm@nokia.com>
This commit is contained in:
Leandro Melo
2011-09-06 11:50:58 +02:00
committed by Leandro T. C. Melo
parent b237464045
commit d91c218d54
4 changed files with 60 additions and 8 deletions

View File

@@ -59,6 +59,7 @@
#include <QtDebug>
#include <algorithm>
#include <QtCore/QList>
namespace CPlusPlus {
@@ -1227,11 +1228,33 @@ void Preprocessor::processDefine(TokenIterator firstToken, TokenIterator lastTok
// ### make me fast!
const char *startOfDefinition = startOfToken(*tk);
const char *endOfDefinition = endOfToken(lastToken[- 1]);
QByteArray definition(startOfDefinition,
endOfDefinition - startOfDefinition);
definition.replace("\\\n", " ");
definition.replace('\n', ' ');
macro.setDefinition(definition.trimmed());
// It could be that the start is not really before that end, so the check...
if (startOfDefinition < endOfDefinition) {
QList<unsigned> lineBreaks;
lineBreaks.reserve(4); // A reasonable guess...?
QByteArray definition;
definition.reserve(endOfDefinition - startOfDefinition);
while (startOfDefinition != endOfDefinition) {
bool replace = false;
if (*startOfDefinition == '\n'
|| (startOfDefinition + 1 != endOfDefinition
&& *startOfDefinition == '\\'
&& *(startOfDefinition + 1) == '\n')) {
replace = true;
if (*startOfDefinition != '\n')
++startOfDefinition;
}
if (replace) {
definition.append(' ');
lineBreaks.append(definition.length() - 1);
} else {
definition.append(*startOfDefinition);
}
++startOfDefinition;
}
macro.setDefinition(definition.trimmed());
macro.setLineBreaks(lineBreaks);
}
}
env->bind(macro);