moc: Fix parsing of complex defines defined via command line

Since now in Qt5 the moc does full macro substitution, it needs to handle
the defines passed is command argument, even if they span over multiple
tokens, or if they do not have any token.

Example:
 moc '-DCOMPLEX=QVector<int>' '-DEMPTY=' foo.h

[ChangeLog][moc] Fixed passing -D of a macro defined to something more
complex than a single identifier.

Task-number: QTBUG-33668
Change-Id: Ie8131de215f1659a24af4778d52ee40cda19759f
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@digia.com>
This commit is contained in:
Olivier Goffart 2013-09-25 21:36:15 +02:00 committed by The Qt Project
parent 39262323d3
commit 55659fb5a4
6 changed files with 22 additions and 4 deletions

View File

@ -343,7 +343,8 @@ int runMoc(int argc, char **argv)
parser.showHelp(1);
}
Macro macro;
macro.symbols += Symbol(0, PP_IDENTIFIER, value);
macro.symbols = Preprocessor::tokenize(value, 1, Preprocessor::TokenizeDefine);
macro.symbols.removeLast(); // remove the EOF symbol
pp.macros.insert(name, macro);
}
foreach (const QString &arg, parser.values(undefineOption)) {

View File

@ -158,8 +158,7 @@ bool Preprocessor::skipBranch()
}
enum TokenizeMode { TokenizeCpp, TokenizePreprocessor, PreparePreprocessorStatement, TokenizePreprocessorStatement, TokenizeInclude, PrepareDefine, TokenizeDefine };
static Symbols tokenize(const QByteArray &input, int lineNum = 1, TokenizeMode mode = TokenizeCpp)
Symbols Preprocessor::tokenize(const QByteArray& input, int lineNum, Preprocessor::TokenizeMode mode)
{
Symbols symbols;
const char *begin = input.constData();

View File

@ -89,6 +89,8 @@ public:
int evaluateCondition();
enum TokenizeMode { TokenizeCpp, TokenizePreprocessor, PreparePreprocessorStatement, TokenizePreprocessorStatement, TokenizeInclude, PrepareDefine, TokenizeDefine };
static Symbols tokenize(const QByteArray &input, int lineNum = 1, TokenizeMode mode = TokenizeCpp);
private:
void until(Token);

View File

@ -42,3 +42,6 @@ DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
# Ensure that plugin_metadata.h are moc-ed with some extra -M arguments:
QMAKE_MOC_OPTIONS += -Muri=com.company.app -Muri=com.company.app.private
# Define macro on the command lines used in parse-defines.h
QMAKE_MOC_OPTIONS += "-DDEFINE_CMDLINE_EMPTY=" "\"-DDEFINE_CMDLINE_SIGNAL=void cmdlineSignal(const QMap<int, int> &i)\""

View File

@ -79,9 +79,16 @@
#define PD_ADD_SUFFIX(x) PD_DEFINE1(x,_SUFFIX)
#define PD_DEFINE_ITSELF PD_ADD_SUFFIX(PD_DEFINE_ITSELF)
#ifndef Q_MOC_RUN
// macro defined on the command line (in tst_moc.pro)
#define DEFINE_CMDLINE_EMPTY
#define DEFINE_CMDLINE_SIGNAL void cmdlineSignal(const QMap<int, int> &i)
#endif
PD_BEGIN_NAMESPACE
class PD_CLASSNAME : public QObject
class DEFINE_CMDLINE_EMPTY PD_CLASSNAME DEFINE_CMDLINE_EMPTY
: public DEFINE_CMDLINE_EMPTY QObject DEFINE_CMDLINE_EMPTY
{
Q_OBJECT
Q_CLASSINFO("TestString", PD_STRINGIFY(PD_CLASSNAME))
@ -140,6 +147,9 @@ public slots:
void PD_DEFINE_ITSELF(int) {}
signals:
DEFINE_CMDLINE_SIGNAL;
};
#undef QString

View File

@ -3037,6 +3037,9 @@ void tst_Moc::parseDefines()
index = mo->indexOfSlot("PD_DEFINE_ITSELF_SUFFIX(int)");
QVERIFY(index != -1);
index = mo->indexOfSignal("cmdlineSignal(QMap<int,int>)");
QVERIFY(index != -1);
}
void tst_Moc::preprocessorOnly()