diff --git a/src/libs/cplusplus/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp index 48736f805ebd389fb838c7c901a02e3dbce411a4..05a7a083d384e8730e3d336665ef5f139eb2fdab 100644 --- a/src/libs/cplusplus/pp-engine.cpp +++ b/src/libs/cplusplus/pp-engine.cpp @@ -906,7 +906,49 @@ bool Preprocessor::handleIdentifier(PPToken *tk) { ScopedBoolSwap s(m_state.m_inPreprocessorDirective, true); - Macro *macro = m_env->resolve(tk->asByteArrayRef()); + static const QByteArray ppLine("__LINE__"); + static const QByteArray ppFile("__FILE__"); + static const QByteArray ppDate("__DATE__"); + static const QByteArray ppTime("__TIME__"); + + ByteArrayRef macroNameRef = tk->asByteArrayRef(); + + if (macroNameRef.size() == 8 + && macroNameRef[0] == '_' + && macroNameRef[1] == '_') { + PPToken newTk; + if (macroNameRef == ppLine) { + QByteArray txt = QByteArray::number(tk->lineno); + newTk = generateToken(T_STRING_LITERAL, txt.constData(), txt.size(), tk->lineno, false); + } else if (macroNameRef == ppFile) { + QByteArray txt; + txt.append('"'); + txt.append(m_env->currentFileUtf8); + txt.append('"'); + newTk = generateToken(T_STRING_LITERAL, txt.constData(), txt.size(), tk->lineno, false); + } else if (macroNameRef == ppDate) { + QByteArray txt; + txt.append('"'); + txt.append(QDate::currentDate().toString().toUtf8()); + txt.append('"'); + newTk = generateToken(T_STRING_LITERAL, txt.constData(), txt.size(), tk->lineno, false); + } else if (macroNameRef == ppTime) { + QByteArray txt; + txt.append('"'); + txt.append(QTime::currentTime().toString().toUtf8()); + txt.append('"'); + newTk = generateToken(T_STRING_LITERAL, txt.constData(), txt.size(), tk->lineno, false); + } + + if (newTk.hasSource()) { + newTk.f.newline = tk->newline(); + newTk.f.whitespace = tk->whitespace(); + *tk = newTk; + return false; + } + } + + Macro *macro = m_env->resolve(macroNameRef); if (!macro || (tk->expanded() && m_state.m_tokenBuffer diff --git a/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp b/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp index 7d3f44c06b6809d9202a750d78c580b0c60f7373..2594bc692f6f796483c106f4bada75c46e34eb75 100644 --- a/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp +++ b/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp @@ -334,6 +334,7 @@ private slots: void unfinished_function_like_macro_call(); void nasty_macro_expansion(); void glib_attribute(); + void builtin__FILE__(); void blockSkipping(); void includes_1(); void dont_eagerly_expand(); @@ -783,6 +784,23 @@ void tst_Preprocessor::glib_attribute() QCOMPARE(preprocessed, result____); } +void tst_Preprocessor::builtin__FILE__() +{ + Client *client = 0; // no client. + Environment env; + + Preprocessor preprocess(client, &env); + QByteArray preprocessed = preprocess.run( + QLatin1String("some-file.c"), + QByteArray("const char *f = __FILE__\n" + )); + const QByteArray result____ = + "# 1 \"some-file.c\"\n" + "const char *f = \"some-file.c\"\n"; + + QCOMPARE(preprocessed, result____); +} + void tst_Preprocessor::comparisons_data() { QTest::addColumn<QString>("infile");