Commit 5d2cd2e5 authored by Orgad Shaneh's avatar Orgad Shaneh Committed by Orgad Shaneh

C++: Fix handling of #undef

* If the macro is defined before, track its reference
* Synchronize environment line before calling remove, which
  currently sets incorrect line
* Set macro offset

Task-number: QTCREATORBUG-10454
Change-Id: I480d16423a976a025bb8c71046610a46f9d7b0fd
Reviewed-by: default avatarNikolai Kosjar <nikolai.kosjar@digia.com>
parent 8ff63de7
......@@ -1951,10 +1951,19 @@ void Preprocessor::handleUndefDirective(PPToken *tk)
lex(tk); // consume "undef" token
if (tk->is(T_IDENTIFIER)) {
const ByteArrayRef macroName = tk->asByteArrayRef();
const Macro *macro = m_env->remove(macroName);
const unsigned offset = tk->offset + m_state.m_offsetRef;
// Track macro use if previously defined
if (m_client) {
if (const Macro *existingMacro = m_env->resolve(macroName))
m_client->notifyMacroReference(offset, tk->lineno, *existingMacro);
}
synchronizeOutputLines(*tk);
Macro *macro = m_env->remove(macroName);
if (m_client && macro)
if (m_client && macro) {
macro->setOffset(offset);
m_client->macroAdded(*macro);
}
lex(tk); // consume macro name
#ifndef NO_DEBUG
} else {
......
......@@ -374,6 +374,7 @@ private slots:
void include_guard_data();
void empty_trailing_lines();
void empty_trailing_lines_data();
void undef();
};
// Remove all #... lines, and 'simplify' string, to allow easily comparing the result
......@@ -1739,6 +1740,46 @@ void tst_Preprocessor::empty_trailing_lines_data()
);
}
void tst_Preprocessor::undef()
{
Environment env;
QByteArray output;
MockClient client(&env, &output);
Preprocessor preprocess(&client, &env);
QByteArray input =
"#define FOO\n"
"#define FOO2\n"
"#undef FOO\n"
"#undef BAR\n";
preprocess.run(QLatin1String("<stdin>"), input);
QCOMPARE(env.macroCount(), 4U);
Macro *macro = env.macroAt(0);
QCOMPARE(macro->name(), QByteArray("FOO"));
QCOMPARE(macro->offset(), 8U);
QCOMPARE(macro->line(), 1U);
QVERIFY(!macro->isHidden());
macro = env.macroAt(1);
QCOMPARE(macro->name(), QByteArray("FOO2"));
QCOMPARE(macro->offset(), 20U);
QCOMPARE(macro->line(), 2U);
QVERIFY(!macro->isHidden());
macro = env.macroAt(2);
QCOMPARE(macro->name(), QByteArray("FOO"));
QCOMPARE(macro->offset(), 32U);
QCOMPARE(macro->line(), 3U);
QVERIFY(macro->isHidden());
macro = env.macroAt(3);
QCOMPARE(macro->name(), QByteArray("BAR"));
QCOMPARE(macro->offset(), 43U);
QCOMPARE(macro->line(), 4U);
QVERIFY(macro->isHidden());
QList<QByteArray> macros = client.definedMacros();
QVERIFY(macros.contains("FOO"));
QVERIFY(macros.contains("FOO2"));
QCOMPARE(client.macroUsesLine()["FOO"], (QList<unsigned>() << 3U));
QVERIFY(client.macroUsesLine()["BAR"].isEmpty());
}
void tst_Preprocessor::compare_input_output(bool keepComments)
{
QFETCH(QByteArray, input);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment