Preprocessor: fix expanding macro arguments.

Expanding macro arguments can add or remove argument for a nested macro,
so the actual parameters list was not correct.

Also, remove unused arguments reference list and reserve space for the
expected number of arguments.

Change-Id: I4cf369cbb3909927c6bf65750bd715fa6f070fad
Reviewed-by: Erik Verbruggen <erik.verbruggen@nokia.com>
This commit is contained in:
Francois Ferrand
2012-03-16 14:22:17 +01:00
committed by Erik Verbruggen
parent 3e9105e401
commit 558b6e08ae
3 changed files with 50 additions and 13 deletions

View File

@@ -103,7 +103,6 @@ const char *MacroExpander::operator()(const char *first, const char *last,
const char *MacroExpander::expand(const char *__first, const char *__last,
QByteArray *__result)
{
const char *start = __first;
__first = skip_blanks (__first, __last);
lines = skip_blanks.lines;
@@ -362,20 +361,18 @@ const char *MacroExpander::expand(const char *__first, const char *__last,
}
QVector<QByteArray> actuals;
QVector<MacroArgumentReference> actuals_ref;
actuals.reserve (5);
actuals.reserve(macro->formals().size());
++arg_it; // skip '('
MacroExpander expand_actual (env, frame);
const char *arg_end = skip_argument_variadics (actuals, macro, arg_it, __last);
const char *arg_end = skip_argument(arg_it, __last);
if (arg_it != arg_end || (arg_end != __last && *arg_end == ','))
{
actuals_ref.append(MacroArgumentReference(start_offset + (arg_it-start), arg_end - arg_it));
const QByteArray actual (arg_it, arg_end - arg_it);
const QByteArray actual(arg_it, arg_end - arg_it);
QByteArray expanded;
expand_actual (actual.constBegin (), actual.constEnd (), &expanded);
actuals.push_back (expanded);
expand_actual(actual.constBegin (), actual.constEnd (), &expanded);
pushActuals(actuals, macro, expanded);
arg_it = arg_end;
}
@@ -383,12 +380,11 @@ const char *MacroExpander::expand(const char *__first, const char *__last,
{
++arg_it; // skip ','
arg_end = skip_argument_variadics (actuals, macro, arg_it, __last);
actuals_ref.append(MacroArgumentReference(start_offset + (arg_it-start), arg_end - arg_it));
const QByteArray actual (arg_it, arg_end - arg_it);
arg_end = skip_argument(arg_it, __last);
const QByteArray actual(arg_it, arg_end - arg_it);
QByteArray expanded;
expand_actual (actual.constBegin (), actual.constEnd (), &expanded);
actuals.push_back (expanded);
expand_actual(actual.constBegin (), actual.constEnd (), &expanded);
pushActuals(actuals, macro, expanded);
arg_it = arg_end;
}
@@ -425,3 +421,29 @@ const char *MacroExpander::skip_argument_variadics (QVector<QByteArray> const &_
return arg_end;
}
void MacroExpander::pushActuals(QVector<QByteArray> & actuals, Macro *__macro, const QByteArray& expanded)
{
if (__macro->isVariadic() && actuals.count() == __macro->formals().count()) {
//already enough params --> append to the last one
QByteArray& b = actuals.last();
b.append(",");
b.append(expanded.trimmed());
}
else {
const char * __first = expanded.constData();
const char * __last = __first + expanded.length();
const char * arg_it = __first;
const char *arg_end = skip_argument_variadics(actuals, __macro, arg_it, __last);
actuals.push_back(QByteArray(arg_it, arg_end - arg_it).trimmed());
arg_it = arg_end;
while (arg_it != __last) {
++arg_it; // skip ','
const char *arg_end = skip_argument_variadics(actuals, __macro, arg_it, __last);
actuals.push_back(QByteArray(arg_it, arg_end - arg_it).trimmed());
arg_it = arg_end;
}
}
}

View File

@@ -98,6 +98,7 @@ public:
const char *skip_argument_variadics(const QVector<QByteArray> &actuals,
Macro *macro,
const char *first, const char *last);
void pushActuals(QVector<QByteArray> & actuals, Macro *__macro, const QByteArray& expanded);
public: // attributes
int lines;