diff options
Diffstat (limited to 'src/tools/moc/preprocessor.cpp')
-rw-r--r-- | src/tools/moc/preprocessor.cpp | 103 |
1 files changed, 54 insertions, 49 deletions
diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp index a0c0b7ffaa..11ea8d417e 100644 --- a/src/tools/moc/preprocessor.cpp +++ b/src/tools/moc/preprocessor.cpp @@ -12,6 +12,8 @@ QT_BEGIN_NAMESPACE +using namespace QtMiscUtils; + #include "ppkeywords.cpp" #include "keywords.cpp" @@ -212,7 +214,9 @@ Symbols Preprocessor::tokenize(const QByteArray& input, int lineNum, Preprocesso data -= 2; break; case DIGIT: - while (is_digit_char(*data) || *data == '\'') + { + bool hasSeenTokenSeparator = false;; + while (isAsciiDigit(*data) || (hasSeenTokenSeparator = *data == '\'')) ++data; if (!*data || *data != '.') { token = INTEGER_LITERAL; @@ -221,22 +225,30 @@ Symbols Preprocessor::tokenize(const QByteArray& input, int lineNum, Preprocesso || *data == 'b' || *data == 'B') && *lexem == '0') { ++data; - while (is_hex_char(*data) || *data == '\'') + while (isHexDigit(*data) || (hasSeenTokenSeparator = *data == '\'')) + ++data; + } else if (*data == 'L') // TODO: handle other suffixes + ++data; + if (!hasSeenTokenSeparator) { + while (is_ident_char(*data)) { ++data; + token = IDENTIFIER; + } } break; } token = FLOATING_LITERAL; ++data; Q_FALLTHROUGH(); + } case FLOATING_LITERAL: - while (is_digit_char(*data) || *data == '\'') + while (isAsciiDigit(*data) || *data == '\'') ++data; if (*data == '+' || *data == '-') ++data; if (*data == 'e' || *data == 'E') { ++data; - while (is_digit_char(*data) || *data == '\'') + while (isAsciiDigit(*data) || *data == '\'') ++data; } if (*data == 'f' || *data == 'F' @@ -315,16 +327,7 @@ Symbols Preprocessor::tokenize(const QByteArray& input, int lineNum, Preprocesso continue; //ignore } } -#ifdef USE_LEXEM_STORE - if (!Preprocessor::preprocessOnly - && token != IDENTIFIER - && token != STRING_LITERAL - && token != FLOATING_LITERAL - && token != INTEGER_LITERAL) - symbols += Symbol(lineNum, token); - else -#endif - symbols += Symbol(lineNum, token, input, lexem-begin, data-lexem); + symbols += Symbol(lineNum, token, input, lexem-begin, data-lexem); } else { // Preprocessor @@ -390,7 +393,7 @@ Symbols Preprocessor::tokenize(const QByteArray& input, int lineNum, Preprocesso token = PP_CHARACTER_LITERAL; break; case PP_DIGIT: - while (is_digit_char(*data) || *data == '\'') + while (isAsciiDigit(*data) || *data == '\'') ++data; if (!*data || *data != '.') { token = PP_INTEGER_LITERAL; @@ -398,22 +401,23 @@ Symbols Preprocessor::tokenize(const QByteArray& input, int lineNum, Preprocesso (*data == 'x' || *data == 'X') && *lexem == '0') { ++data; - while (is_hex_char(*data) || *data == '\'') + while (isHexDigit(*data) || *data == '\'') ++data; - } + } else if (*data == 'L') // TODO: handle other suffixes + ++data; break; } token = PP_FLOATING_LITERAL; ++data; Q_FALLTHROUGH(); case PP_FLOATING_LITERAL: - while (is_digit_char(*data) || *data == '\'') + while (isAsciiDigit(*data) || *data == '\'') ++data; if (*data == '+' || *data == '-') ++data; if (*data == 'e' || *data == 'E') { ++data; - while (is_digit_char(*data) || *data == '\'') + while (isAsciiDigit(*data) || *data == '\'') ++data; } if (*data == 'f' || *data == 'F' @@ -495,22 +499,14 @@ Symbols Preprocessor::tokenize(const QByteArray& input, int lineNum, Preprocesso } if (mode == PreparePreprocessorStatement) continue; -#ifdef USE_LEXEM_STORE - if (token != PP_IDENTIFIER - && token != PP_STRING_LITERAL - && token != PP_FLOATING_LITERAL - && token != PP_INTEGER_LITERAL) - symbols += Symbol(lineNum, token); - else -#endif - symbols += Symbol(lineNum, token, input, lexem-begin, data-lexem); + symbols += Symbol(lineNum, token, input, lexem-begin, data-lexem); } } symbols += Symbol(); // eof symbol return symbols; } -void Preprocessor::macroExpand(Symbols *into, Preprocessor *that, const Symbols &toExpand, int &index, +void Preprocessor::macroExpand(Symbols *into, Preprocessor *that, const Symbols &toExpand, qsizetype &index, int lineNum, bool one, const QSet<QByteArray> &excludeSymbols) { SymbolStack symbols; @@ -618,19 +614,22 @@ Symbols Preprocessor::macroExpandIdentifier(Preprocessor *that, SymbolStack &sym HashHash } mode = Normal; - for (int i = 0; i < macro.symbols.size(); ++i) { - const Symbol &s = macro.symbols.at(i); + const auto end = macro.symbols.cend(); + auto it = macro.symbols.cbegin(); + const auto lastSym = std::prev(macro.symbols.cend(), !macro.symbols.isEmpty() ? 1 : 0); + for (; it != end; ++it) { + const Symbol &s = *it; if (s.token == HASH || s.token == PP_HASHHASH) { mode = (s.token == HASH ? Hash : HashHash); continue; } - int index = macro.arguments.indexOf(s); + const qsizetype index = macro.arguments.indexOf(s); if (mode == Normal) { if (index >= 0 && index < arguments.size()) { // each argument undoergoes macro expansion if it's not used as part of a # or ## - if (i == macro.symbols.size() - 1 || macro.symbols.at(i + 1).token != PP_HASHHASH) { + if (it == lastSym || std::next(it)->token != PP_HASHHASH) { Symbols arg = arguments.at(index); - int idx = 1; + qsizetype idx = 1; macroExpand(&expansion, that, arg, idx, lineNum, false, symbols.excludeSymbols()); } else { expansion += arguments.at(index); @@ -649,9 +648,9 @@ Symbols Preprocessor::macroExpandIdentifier(Preprocessor *that, SymbolStack &sym const Symbols &arg = arguments.at(index); QByteArray stringified; - for (int i = 0; i < arg.size(); ++i) { - stringified += arg.at(i).lexem(); - } + for (const Symbol &sym : arg) + stringified += sym.lexem(); + stringified.replace('"', "\\\""); stringified.prepend('"'); stringified.append('"'); @@ -685,8 +684,8 @@ Symbols Preprocessor::macroExpandIdentifier(Preprocessor *that, SymbolStack &sym if (index >= 0 && index < arguments.size()) { const Symbols &arg = arguments.at(index); - for (int i = 1; i < arg.size(); ++i) - expansion += arg.at(i); + if (!arg.isEmpty()) + expansion.append(arg.cbegin() + 1, arg.cend()); } } mode = Normal; @@ -927,7 +926,11 @@ int PP_Expression::primary_expression() test(PP_RPAREN); } else { next(); - value = lexem().toInt(nullptr, 0); + const QByteArray &lex = lexem(); + auto lexView = QByteArrayView(lex); + if (lex.endsWith('L')) + lexView.chop(1); + value = lexView.toInt(nullptr, 0); } return value; } @@ -966,7 +969,7 @@ static void mergeStringLiterals(Symbols *_symbols) for (Symbols::iterator i = symbols.begin(); i != symbols.end(); ++i) { if (i->token == STRING_LITERAL) { Symbols::Iterator mergeSymbol = i; - int literalsLength = mergeSymbol->len; + qsizetype literalsLength = mergeSymbol->len; while (++i != symbols.end() && i->token == STRING_LITERAL) literalsLength += i->len - 2; // no quotes @@ -980,7 +983,7 @@ static void mergeStringLiterals(Symbols *_symbols) for (Symbols::iterator j = mergeSymbol + 1; j != i; ++j) mergeSymbolLexem.append(j->lex.constData() + j->from + 1, j->len - 2); // append j->unquotedLexem() mergeSymbolLexem.append('"'); - mergeSymbol->len = mergeSymbol->lex.length(); + mergeSymbol->len = mergeSymbol->lex.size(); mergeSymbol->from = 0; i = symbols.erase(mergeSymbol + 1, i); } @@ -1000,10 +1003,12 @@ static QByteArray searchIncludePaths(const QList<Parser::IncludePath> &includepa fprintf(stderr, "debug-includes: searching for '%s'\n", include.constData()); } - for (int j = 0; j < includepaths.size() && !fi.exists(); ++j) { - const Parser::IncludePath &p = includepaths.at(j); + for (const Parser::IncludePath &p : includepaths) { + if (fi.exists()) + break; + if (p.isFrameworkPath) { - const int slashPos = include.indexOf('/'); + const qsizetype slashPos = include.indexOf('/'); if (slashPos == -1) continue; fi.setFile(QString::fromLocal8Bit(p.path + '/' + include.left(slashPos) + ".framework/Headers/"), @@ -1099,7 +1104,7 @@ void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed) continue; Symbols saveSymbols = symbols; - int saveIndex = index; + qsizetype saveIndex = index; // phase 1: get rid of backslash-newlines input = cleaned(input); @@ -1134,14 +1139,14 @@ void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed) } else { macro.isFunction = false; } - int start = index; + qsizetype start = index; until(PP_NEWLINE); macro.symbols.reserve(index - start - 1); // remove whitespace where there shouldn't be any: // Before and after the macro, after a # and around ## Token lastToken = HASH; // skip shitespace at the beginning - for (int i = start; i < index - 1; ++i) { + for (qsizetype i = start; i < index - 1; ++i) { Token token = symbols.at(i).token; if (token == WHITESPACE) { if (lastToken == PP_HASH || lastToken == HASH || @@ -1284,7 +1289,7 @@ void Preprocessor::parseDefineArguments(Macro *m) if (!test(PP_RPAREN)) error("missing ')' in macro argument list"); break; - } else if (!is_identifier(l.constData(), l.length())) { + } else if (!is_identifier(l.constData(), l.size())) { error("Unexpected character in macro argument list."); } } |