From 34a3b63dc7d3b09342647537d378f5a55d0c81f0 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 7 Sep 2012 15:13:03 +0200 Subject: Correctly expand macros without arguments in moc This helps e.g. cases where a namespace is defined through a macro and moc doesn't see it at all. Expanding macros with arguments is significantly more work, and should happen in a separate commit. Change-Id: Ic8d0443d06fab2ed343115d8c43022f2c67ec3cd Reviewed-by: Qt Doc Bot Reviewed-by: Olivier Goffart --- src/tools/moc/preprocessor.cpp | 65 ++++++++++++++++++++++++++++++++---------- src/tools/moc/preprocessor.h | 1 + 2 files changed, 51 insertions(+), 15 deletions(-) (limited to 'src/tools') diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp index dc5136d4a6..4d4b571742 100644 --- a/src/tools/moc/preprocessor.cpp +++ b/src/tools/moc/preprocessor.cpp @@ -157,14 +157,14 @@ bool Preprocessor::skipBranch() } -enum TokenizeMode { TokenizeCpp, TokenizePreprocessor, PreparePreprocessorStatement, TokenizePreprocessorStatement, TokenizeInclude }; +enum TokenizeMode { TokenizeCpp, TokenizePreprocessor, PreparePreprocessorStatement, TokenizePreprocessorStatement, TokenizeInclude, PrepareDefine, TokenizeDefine }; static Symbols tokenize(const QByteArray &input, int lineNum = 1, TokenizeMode mode = TokenizeCpp) { Symbols symbols; const char *begin = input.constData(); const char *data = begin; while (*data) { - if (mode == TokenizeCpp) { + if (mode == TokenizeCpp || mode == TokenizeDefine) { int column = 0; const char *lexem = data; @@ -278,6 +278,11 @@ static Symbols tokenize(const QByteArray &input, int lineNum = 1, TokenizeMode m break; case NEWLINE: ++lineNum; + if (mode == TokenizeDefine) { + mode = TokenizeCpp; + // emit the newline token + break; + } continue; case BACKSLASH: { @@ -375,6 +380,9 @@ static Symbols tokenize(const QByteArray &input, int lineNum = 1, TokenizeMode m case NOTOKEN: ++data; break; + case PP_DEFINE: + mode = PrepareDefine; + break; case PP_IFDEF: symbols += Symbol(lineNum, PP_IF); symbols += Symbol(lineNum, PP_DEFINED); @@ -441,6 +449,16 @@ static Symbols tokenize(const QByteArray &input, int lineNum = 1, TokenizeMode m while (is_ident_char(*data)) ++data; token = PP_IDENTIFIER; + + if (mode == PrepareDefine) { + symbols += Symbol(lineNum, token, input, lexem-begin, data-lexem); + // make sure we explicitly add the whitespace here, so we can distinguish + // correctly between regular and function macros + if (is_space(*data)) + symbols += Symbol(lineNum, WHITESPACE); + mode = TokenizeDefine; + continue; + } break; case PP_C_COMMENT: if (*data) { @@ -510,6 +528,32 @@ static Symbols tokenize(const QByteArray &input, int lineNum = 1, TokenizeMode m return symbols; } +void Preprocessor::macroExpandIdentifier(const Symbol &s, Symbols &preprocessed, MacroSafeSet safeset) +{ + // not a macro + if (!macros.contains(s)) { + preprocessed += s; + return; + } + + Symbols expanded = macros.value(s).symbols; + + // don't expand macros with arguments for now + if (expanded.size() && expanded.at(0).token == PP_LPAREN) { + preprocessed += s; + return; + } + + for (int i = 0; i < expanded.size(); ++i) { + expanded[i].lineNum = s.lineNum; + if (expanded.at(i).token == PP_IDENTIFIER) + macroExpandIdentifier(expanded.at(i), preprocessed, safeset); + else + preprocessed += expanded.at(i); + } +} + + void Preprocessor::substituteMacro(const MacroName ¯o, Symbols &substituted, MacroSafeSet safeset) { Symbols saveSymbols = symbols; @@ -878,20 +922,11 @@ void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed) macros.remove(name); continue; } - case PP_IDENTIFIER: - { -// if (macros.contains(symbol())) -// ; + case PP_IDENTIFIER: { + // substitute macros + macroExpandIdentifier(symbol(), preprocessed); + continue; } - // we _could_ easily substitute macros by the following - // four lines, but we choose not to. - /* - if (macros.contains(sym.lexem())) { - preprocessed += substitute(macros, symbols, i); - continue; - } - */ - break; case PP_HASH: until(PP_NEWLINE); continue; // skip unknown preprocessor statement diff --git a/src/tools/moc/preprocessor.h b/src/tools/moc/preprocessor.h index 0961f4780d..70121c2102 100644 --- a/src/tools/moc/preprocessor.h +++ b/src/tools/moc/preprocessor.h @@ -81,6 +81,7 @@ public: void substituteMacro(const MacroName ¯o, Symbols &substituted, MacroSafeSet safeset = MacroSafeSet()); void substituteUntilNewline(Symbols &substituted, MacroSafeSet safeset = MacroSafeSet()); + void macroExpandIdentifier(const Symbol &s, Symbols &preprocessed, MacroSafeSet safeset = MacroSafeSet()); int evaluateCondition(); -- cgit v1.2.3