From 558b6e08ae2709549cecdd9698b577c1f8b4f964 Mon Sep 17 00:00:00 2001 From: Francois Ferrand Date: Fri, 16 Mar 2012 14:22:17 +0100 Subject: 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 --- src/libs/cplusplus/pp-macro-expander.cpp | 48 +++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 13 deletions(-) (limited to 'src/libs/cplusplus/pp-macro-expander.cpp') diff --git a/src/libs/cplusplus/pp-macro-expander.cpp b/src/libs/cplusplus/pp-macro-expander.cpp index 3aa53c7d7e..cde82884c0 100644 --- a/src/libs/cplusplus/pp-macro-expander.cpp +++ b/src/libs/cplusplus/pp-macro-expander.cpp @@ -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 actuals; - QVector 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 const &_ return arg_end; } + +void MacroExpander::pushActuals(QVector & 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; + } + } +} -- cgit v1.2.1