2012-10-02 09:12:39 +02:00
|
|
|
/****************************************************************************
|
2011-02-18 14:48:16 +01:00
|
|
|
**
|
2014-01-07 13:27:11 +01:00
|
|
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
2012-10-02 09:12:39 +02:00
|
|
|
** Contact: http://www.qt-project.org/legal
|
2011-02-18 14:48:16 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** This file is part of Qt Creator.
|
2011-02-18 14:48:16 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** Commercial License Usage
|
|
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
|
|
** accordance with the commercial license agreement provided with the
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
|
|
|
** a written agreement between you and Digia. For licensing terms and
|
|
|
|
** conditions see http://qt.digia.com/licensing. For further information
|
|
|
|
** use the contact form at http://qt.digia.com/contact-us.
|
2011-02-18 14:48:16 +01:00
|
|
|
**
|
|
|
|
** GNU Lesser General Public License Usage
|
2012-10-02 09:12:39 +02:00
|
|
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
|
|
** General Public License version 2.1 as published by the Free Software
|
|
|
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
|
|
** packaging of this file. Please review the following information to
|
|
|
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
|
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
|
|
**
|
|
|
|
** In addition, as a special exception, Digia gives you certain additional
|
|
|
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
2011-02-18 14:48:16 +01:00
|
|
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
****************************************************************************/
|
2011-02-18 14:48:16 +01:00
|
|
|
|
2013-03-27 18:54:03 +01:00
|
|
|
#include <cplusplus/pp.h>
|
|
|
|
|
2009-03-02 11:30:43 +01:00
|
|
|
#include <QtTest>
|
2013-08-26 14:58:24 +02:00
|
|
|
#include <QFile>
|
2012-05-29 12:37:55 +02:00
|
|
|
#include <QHash>
|
2014-02-20 21:39:34 +02:00
|
|
|
#include <QSet>
|
2009-03-02 11:30:43 +01:00
|
|
|
|
2010-09-02 15:32:04 +10:00
|
|
|
//TESTED_COMPONENT=src/libs/cplusplus
|
2009-03-03 16:32:08 +01:00
|
|
|
using namespace CPlusPlus;
|
2009-03-02 11:30:43 +01:00
|
|
|
|
2014-01-13 22:57:32 +02:00
|
|
|
typedef QByteArray _;
|
|
|
|
|
2012-03-26 15:18:01 +02:00
|
|
|
#define DUMP_OUTPUT(x) {QByteArray b(x);qDebug("output: [[%s]]", b.replace("\n", "<<\n").constData());}
|
|
|
|
|
|
|
|
|
|
|
|
QByteArray loadSource(const QString &fileName)
|
|
|
|
{
|
2012-11-06 12:41:05 +01:00
|
|
|
QFile inf(QLatin1String(SRCDIR) + QLatin1Char('/') + fileName);
|
2012-03-26 15:18:01 +02:00
|
|
|
if (!inf.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
|
|
qDebug("Cannot open \"%s\"", fileName.toUtf8().constData());
|
|
|
|
return QByteArray();
|
|
|
|
}
|
|
|
|
|
|
|
|
QTextStream ins(&inf);
|
|
|
|
QString source = ins.readAll();
|
|
|
|
inf.close();
|
|
|
|
return source.toUtf8();
|
|
|
|
}
|
|
|
|
|
|
|
|
void saveData(const QByteArray &data, const QString &fileName)
|
|
|
|
{
|
2012-11-06 12:41:05 +01:00
|
|
|
QFile inf(QLatin1String(SRCDIR) + QLatin1Char('/') + fileName);
|
2012-03-26 15:18:01 +02:00
|
|
|
if (!inf.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
|
|
|
qDebug("Cannot open \"%s\"", fileName.toUtf8().constData());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
inf.write(data);
|
|
|
|
inf.close();
|
|
|
|
}
|
|
|
|
|
2012-03-29 17:14:42 +02:00
|
|
|
struct Include
|
|
|
|
{
|
|
|
|
Include(const QString &fileName, Client::IncludeType type, unsigned line)
|
|
|
|
: fileName(fileName), type(type), line(line)
|
|
|
|
{}
|
|
|
|
|
|
|
|
QString fileName;
|
|
|
|
Client::IncludeType type;
|
|
|
|
unsigned line;
|
|
|
|
};
|
2012-04-24 18:29:09 +02:00
|
|
|
|
|
|
|
QDebug &operator<<(QDebug& d, const Include &i)
|
|
|
|
{
|
2012-03-29 17:14:42 +02:00
|
|
|
d << '[' << i.fileName
|
2012-04-24 18:29:09 +02:00
|
|
|
<< ',' << (i.type == Client::IncludeGlobal ? "Global"
|
|
|
|
: (i.type == Client::IncludeLocal ? "Local" : "Unknown"))
|
2012-03-29 17:14:42 +02:00
|
|
|
<< ',' << i.line
|
|
|
|
<< ']';
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
2012-04-24 18:29:09 +02:00
|
|
|
class MockClient : public Client
|
2012-03-26 15:18:01 +02:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
struct Block {
|
2012-04-24 18:29:09 +02:00
|
|
|
Block() : start(0), end(0) {}
|
|
|
|
Block(unsigned start) : start(start), end(0) {}
|
2012-03-26 15:18:01 +02:00
|
|
|
|
|
|
|
unsigned start;
|
|
|
|
unsigned end;
|
|
|
|
};
|
|
|
|
|
|
|
|
public:
|
|
|
|
MockClient(Environment *env, QByteArray *output)
|
|
|
|
: m_env(env)
|
|
|
|
, m_output(output)
|
|
|
|
, m_pp(this, env)
|
|
|
|
, m_includeDepth(0)
|
|
|
|
{}
|
|
|
|
|
|
|
|
virtual ~MockClient() {}
|
|
|
|
|
2012-04-02 14:57:13 +02:00
|
|
|
virtual void macroAdded(const Macro & macro)
|
|
|
|
{
|
|
|
|
m_definedMacros.append(macro.name());
|
|
|
|
m_definedMacrosLine.append(macro.line());
|
|
|
|
}
|
2012-03-26 15:18:01 +02:00
|
|
|
|
2014-05-09 10:04:13 -04:00
|
|
|
virtual void passedMacroDefinitionCheck(unsigned /*bytesOffset*/,
|
|
|
|
unsigned /*utf16charsOffset*/,
|
2014-02-20 21:39:34 +02:00
|
|
|
unsigned line,
|
|
|
|
const Macro ¯o)
|
|
|
|
{
|
|
|
|
m_definitionsResolvedFromLines[macro.name()].append(line);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void failedMacroDefinitionCheck(unsigned /*offset*/,
|
2014-05-09 10:04:13 -04:00
|
|
|
unsigned /*utf16charsOffset*/,
|
2014-02-20 21:39:34 +02:00
|
|
|
const ByteArrayRef &name)
|
|
|
|
{
|
|
|
|
m_unresolvedDefines.insert(name.toByteArray());
|
|
|
|
}
|
2012-03-26 15:18:01 +02:00
|
|
|
|
2014-05-09 10:04:13 -04:00
|
|
|
virtual void notifyMacroReference(unsigned bytesOffset, unsigned /*utf16charsOffset*/,
|
|
|
|
unsigned line, const Macro ¯o)
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
{
|
|
|
|
m_macroUsesLine[macro.name()].append(line);
|
2014-05-09 10:04:13 -04:00
|
|
|
m_expandedMacrosOffset.append(bytesOffset);
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
}
|
|
|
|
|
2014-05-09 10:04:13 -04:00
|
|
|
virtual void startExpandingMacro(unsigned bytesOffset,
|
|
|
|
unsigned /*utf16charsOffset*/,
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
unsigned line,
|
2012-05-29 12:37:55 +02:00
|
|
|
const Macro ¯o,
|
2012-06-12 14:51:48 +02:00
|
|
|
const QVector<MacroArgumentReference> &actuals
|
|
|
|
= QVector<MacroArgumentReference>())
|
2012-04-02 13:46:53 +02:00
|
|
|
{
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
m_expandedMacros.append(macro.name());
|
2014-05-09 10:04:13 -04:00
|
|
|
m_expandedMacrosOffset.append(bytesOffset);
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
m_macroUsesLine[macro.name()].append(line);
|
2012-06-12 14:51:48 +02:00
|
|
|
m_macroArgsCount.append(actuals.size());
|
2012-04-02 13:46:53 +02:00
|
|
|
}
|
2012-03-26 15:18:01 +02:00
|
|
|
|
2012-04-24 18:29:09 +02:00
|
|
|
virtual void stopExpandingMacro(unsigned /*offset*/, const Macro &/*macro*/) {}
|
2012-03-26 15:18:01 +02:00
|
|
|
|
2014-05-09 10:04:13 -04:00
|
|
|
virtual void startSkippingBlocks(unsigned utf16charsOffset)
|
|
|
|
{ m_skippedBlocks.append(Block(utf16charsOffset)); }
|
2012-03-26 15:18:01 +02:00
|
|
|
|
2014-05-09 10:04:13 -04:00
|
|
|
virtual void stopSkippingBlocks(unsigned utf16charsOffset)
|
|
|
|
{ m_skippedBlocks.last().end = utf16charsOffset; }
|
2012-03-26 15:18:01 +02:00
|
|
|
|
2014-07-16 11:25:15 +02:00
|
|
|
virtual void sourceNeeded(unsigned line, const QString &includedFileName, IncludeType mode,
|
|
|
|
const QStringList &initialIncludes = QStringList())
|
2012-03-26 15:18:01 +02:00
|
|
|
{
|
2014-07-16 11:25:15 +02:00
|
|
|
Q_UNUSED(initialIncludes)
|
2012-03-29 17:14:42 +02:00
|
|
|
#if 1
|
|
|
|
m_recordedIncludes.append(Include(includedFileName, mode, line));
|
2013-05-15 10:36:14 +02:00
|
|
|
Q_UNUSED(m_env);
|
|
|
|
Q_UNUSED(m_includeDepth);
|
2012-03-29 17:14:42 +02:00
|
|
|
#else
|
|
|
|
Q_UNUSED(line);
|
|
|
|
|
2012-03-26 15:18:01 +02:00
|
|
|
QString resolvedFileName;
|
|
|
|
if (mode == IncludeLocal)
|
|
|
|
resolvedFileName = resolveLocally(m_env->currentFile, includedFileName);
|
|
|
|
else
|
|
|
|
resolvedFileName = resolveGlobally(includedFileName);
|
|
|
|
|
|
|
|
// qDebug("resolved [[%s]] to [[%s]] from [[%s]] (%s)\n",
|
|
|
|
// includedFileName.toUtf8().constData(),
|
|
|
|
// resolvedFileName.toUtf8().constData(),
|
|
|
|
// currentFileName.toUtf8().constData(),
|
|
|
|
// (mode == IncludeLocal) ? "locally" : "globally");
|
|
|
|
|
|
|
|
if (resolvedFileName.isEmpty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
++m_includeDepth;
|
|
|
|
// qDebug("%5d %s %s", m_includeDepth, QByteArray(m_includeDepth, '+').constData(), resolvedFileName.toUtf8().constData());
|
|
|
|
sourceNeeded(resolvedFileName);
|
|
|
|
--m_includeDepth;
|
2012-03-29 17:14:42 +02:00
|
|
|
#endif
|
2012-03-26 15:18:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
QString resolveLocally(const QString ¤tFileName,
|
2012-04-24 18:29:09 +02:00
|
|
|
const QString &includedFileName) const
|
2012-03-26 15:18:01 +02:00
|
|
|
{
|
|
|
|
QDir dir;
|
|
|
|
if (currentFileName.isEmpty())
|
|
|
|
dir = QDir::current();
|
|
|
|
else
|
|
|
|
dir = QFileInfo(currentFileName).dir();
|
|
|
|
const QFileInfo inc(dir, includedFileName);
|
|
|
|
if (inc.exists()) {
|
|
|
|
const QString resolved = inc.filePath();
|
|
|
|
return resolved.toUtf8().constData();
|
|
|
|
} else {
|
|
|
|
// std::cerr<<"Cannot find " << inc.fileName().toUtf8().constData()<<std::endl;
|
|
|
|
return QString();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QString resolveGlobally(const QString ¤tFileName) const
|
|
|
|
{
|
|
|
|
foreach (const QDir &dir, m_includePaths) {
|
|
|
|
QFileInfo f(dir, currentFileName);
|
|
|
|
if (f.exists())
|
|
|
|
return f.filePath();
|
|
|
|
}
|
|
|
|
|
|
|
|
return QString();
|
|
|
|
}
|
|
|
|
|
|
|
|
void setIncludePaths(const QStringList &includePaths)
|
|
|
|
{
|
|
|
|
foreach (const QString &path, includePaths) {
|
|
|
|
QDir dir(path);
|
|
|
|
if (dir.exists())
|
|
|
|
m_includePaths.append(dir);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-30 13:01:32 +02:00
|
|
|
void sourceNeeded(const QString &fileName, bool nolines)
|
2012-03-26 15:18:01 +02:00
|
|
|
{
|
|
|
|
QByteArray src = loadSource(fileName);
|
|
|
|
QVERIFY(!src.isEmpty());
|
2012-04-19 10:35:49 +02:00
|
|
|
*m_output = m_pp.run(fileName, src, nolines, true);
|
2012-03-26 15:18:01 +02:00
|
|
|
}
|
|
|
|
|
2012-12-21 17:08:21 +01:00
|
|
|
virtual void markAsIncludeGuard(const QByteArray ¯oName)
|
|
|
|
{ m_includeGuardMacro = macroName; }
|
|
|
|
|
|
|
|
QByteArray includeGuard() const
|
|
|
|
{ return m_includeGuardMacro; }
|
|
|
|
|
2012-03-26 15:18:01 +02:00
|
|
|
QList<Block> skippedBlocks() const
|
|
|
|
{ return m_skippedBlocks; }
|
|
|
|
|
2012-03-29 17:14:42 +02:00
|
|
|
QList<Include> recordedIncludes() const
|
|
|
|
{ return m_recordedIncludes; }
|
|
|
|
|
2012-04-02 08:46:56 +02:00
|
|
|
QList<QByteArray> expandedMacros() const
|
|
|
|
{ return m_expandedMacros; }
|
|
|
|
|
2012-04-02 13:46:53 +02:00
|
|
|
QList<unsigned> expandedMacrosOffset() const
|
|
|
|
{ return m_expandedMacrosOffset; }
|
|
|
|
|
2012-04-02 14:57:13 +02:00
|
|
|
QList<QByteArray> definedMacros() const
|
|
|
|
{ return m_definedMacros; }
|
|
|
|
|
|
|
|
QList<unsigned> definedMacrosLine() const
|
|
|
|
{ return m_definedMacrosLine; }
|
|
|
|
|
2012-05-29 15:27:56 +02:00
|
|
|
QHash<QByteArray, QList<unsigned> > macroUsesLine() const
|
2012-05-29 12:37:55 +02:00
|
|
|
{ return m_macroUsesLine; }
|
|
|
|
|
2014-02-20 21:39:34 +02:00
|
|
|
QHash<QByteArray, QList<unsigned> > definitionsResolvedFromLines() const
|
|
|
|
{ return m_definitionsResolvedFromLines; }
|
|
|
|
|
|
|
|
QSet<QByteArray> unresolvedDefines() const
|
|
|
|
{ return m_unresolvedDefines; }
|
|
|
|
|
2012-06-12 14:51:48 +02:00
|
|
|
const QList<int> macroArgsCount() const
|
|
|
|
{ return m_macroArgsCount; }
|
|
|
|
|
2012-03-26 15:18:01 +02:00
|
|
|
private:
|
|
|
|
Environment *m_env;
|
|
|
|
QByteArray *m_output;
|
|
|
|
Preprocessor m_pp;
|
|
|
|
QList<QDir> m_includePaths;
|
|
|
|
unsigned m_includeDepth;
|
2012-12-21 17:08:21 +01:00
|
|
|
QByteArray m_includeGuardMacro;
|
2012-03-26 15:18:01 +02:00
|
|
|
QList<Block> m_skippedBlocks;
|
2012-03-29 17:14:42 +02:00
|
|
|
QList<Include> m_recordedIncludes;
|
2012-04-02 08:46:56 +02:00
|
|
|
QList<QByteArray> m_expandedMacros;
|
2012-04-02 13:46:53 +02:00
|
|
|
QList<unsigned> m_expandedMacrosOffset;
|
2012-04-02 14:57:13 +02:00
|
|
|
QList<QByteArray> m_definedMacros;
|
|
|
|
QList<unsigned> m_definedMacrosLine;
|
2012-05-29 15:27:56 +02:00
|
|
|
QHash<QByteArray, QList<unsigned> > m_macroUsesLine;
|
2014-02-20 21:39:34 +02:00
|
|
|
QHash<QByteArray, QList<unsigned> > m_definitionsResolvedFromLines;
|
|
|
|
QSet<QByteArray> m_unresolvedDefines;
|
2012-06-12 14:51:48 +02:00
|
|
|
QList<int> m_macroArgsCount;
|
2012-03-26 15:18:01 +02:00
|
|
|
};
|
|
|
|
|
2012-04-16 11:39:46 +02:00
|
|
|
QT_BEGIN_NAMESPACE
|
2012-04-02 13:46:53 +02:00
|
|
|
namespace QTest {
|
|
|
|
template<> char *toString(const QList<unsigned> &list)
|
|
|
|
{
|
|
|
|
QByteArray ba = "QList<unsigned>(";
|
|
|
|
foreach (const unsigned& item, list) {
|
|
|
|
ba += QTest::toString(item);
|
|
|
|
ba += ',';
|
|
|
|
}
|
|
|
|
if (!list.isEmpty())
|
|
|
|
ba[ba.size() - 1] = ')';
|
|
|
|
return qstrdup(ba.data());
|
|
|
|
}
|
|
|
|
template<> char *toString(const QList<QByteArray> &list)
|
|
|
|
{
|
|
|
|
QByteArray ba = "QList<QByteArray>(";
|
|
|
|
foreach (const QByteArray& item, list) {
|
|
|
|
ba += QTest::toString(item);
|
|
|
|
ba += ',';
|
|
|
|
}
|
|
|
|
if (!list.isEmpty())
|
|
|
|
ba[ba.size() - 1] = ')';
|
|
|
|
return qstrdup(ba.data());
|
|
|
|
}
|
|
|
|
}
|
2012-04-16 11:39:46 +02:00
|
|
|
QT_END_NAMESPACE
|
2012-04-02 13:46:53 +02:00
|
|
|
|
2012-04-24 18:29:09 +02:00
|
|
|
QDebug &operator<<(QDebug& d, const MockClient::Block &b)
|
|
|
|
{
|
|
|
|
d << '[' << b.start << ',' << b.end << ']';
|
|
|
|
return d;
|
|
|
|
}
|
2012-03-26 15:18:01 +02:00
|
|
|
|
2012-04-24 18:29:09 +02:00
|
|
|
class tst_Preprocessor : public QObject
|
2009-03-02 11:30:43 +01:00
|
|
|
{
|
2012-03-26 15:18:01 +02:00
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
protected:
|
2012-03-30 13:01:32 +02:00
|
|
|
QByteArray preprocess(const QString &fileName, QByteArray * /*errors*/, bool nolines) {
|
2012-03-26 15:18:01 +02:00
|
|
|
//### TODO: hook up errors
|
|
|
|
QByteArray output;
|
|
|
|
Environment env;
|
|
|
|
MockClient client(&env, &output);
|
2012-03-30 13:01:32 +02:00
|
|
|
client.sourceNeeded("data/" + fileName, nolines);
|
2012-03-26 15:18:01 +02:00
|
|
|
return output;
|
|
|
|
}
|
2012-04-02 13:46:53 +02:00
|
|
|
static QString simplified(QByteArray buf);
|
2009-03-02 11:30:43 +01:00
|
|
|
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
private:
|
2012-08-07 10:47:38 +02:00
|
|
|
void compare_input_output(bool keepComments = false);
|
2012-06-13 09:50:39 +02:00
|
|
|
|
2012-03-26 15:18:01 +02:00
|
|
|
private slots:
|
2012-03-16 14:06:09 +01:00
|
|
|
void va_args();
|
|
|
|
void named_va_args();
|
2013-04-25 17:13:39 +02:00
|
|
|
void extra_va_args();
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
void defined();
|
|
|
|
void defined_data();
|
2014-02-20 21:39:34 +02:00
|
|
|
void defined_usage();
|
2012-06-12 14:51:48 +02:00
|
|
|
void empty_macro_args();
|
|
|
|
void macro_args_count();
|
2012-03-26 15:18:01 +02:00
|
|
|
void invalid_param_count();
|
2012-04-02 08:46:56 +02:00
|
|
|
void objmacro_expanding_as_fnmacro_notification();
|
2012-04-02 13:46:53 +02:00
|
|
|
void macro_uses();
|
2012-05-29 12:37:55 +02:00
|
|
|
void macro_uses_lines();
|
2012-04-02 08:46:56 +02:00
|
|
|
void macro_arguments_notificatin();
|
2009-03-03 16:32:08 +01:00
|
|
|
void unfinished_function_like_macro_call();
|
2010-02-10 11:04:31 +01:00
|
|
|
void nasty_macro_expansion();
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
void glib_attribute();
|
2013-11-29 10:53:45 +01:00
|
|
|
void builtin__FILE__();
|
2012-03-26 15:18:01 +02:00
|
|
|
void blockSkipping();
|
2012-03-29 17:14:42 +02:00
|
|
|
void includes_1();
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
void dont_eagerly_expand();
|
|
|
|
void dont_eagerly_expand_data();
|
2012-03-26 15:18:01 +02:00
|
|
|
void comparisons_data();
|
|
|
|
void comparisons();
|
2013-01-17 17:26:26 +01:00
|
|
|
void comments_before_args();
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
void comments_within();
|
|
|
|
void comments_within_data();
|
|
|
|
void multitokens_argument();
|
|
|
|
void multitokens_argument_data();
|
2012-08-20 23:11:34 +02:00
|
|
|
void multiline_strings();
|
|
|
|
void multiline_strings_data();
|
2012-08-29 13:21:22 +02:00
|
|
|
void skip_unknown_directives();
|
|
|
|
void skip_unknown_directives_data();
|
2012-12-21 17:08:21 +01:00
|
|
|
void include_guard();
|
|
|
|
void include_guard_data();
|
2013-05-30 15:03:54 +02:00
|
|
|
void empty_trailing_lines();
|
|
|
|
void empty_trailing_lines_data();
|
2014-02-06 23:18:18 +02:00
|
|
|
void undef();
|
2009-03-02 11:30:43 +01:00
|
|
|
};
|
|
|
|
|
2012-04-02 13:46:53 +02:00
|
|
|
// Remove all #... lines, and 'simplify' string, to allow easily comparing the result
|
|
|
|
// Also, remove all unneeded spaces: keep only to ensure identifiers are separated.
|
|
|
|
// NOTE: may not correctly handle underscore in identifiers
|
|
|
|
QString tst_Preprocessor::simplified(QByteArray buf)
|
|
|
|
{
|
|
|
|
QString out;
|
|
|
|
QList<QByteArray> lines = buf.split('\n');
|
2012-04-24 18:29:09 +02:00
|
|
|
foreach (const QByteArray &line, lines) {
|
2012-04-02 13:46:53 +02:00
|
|
|
if (!line.startsWith('#')) {
|
|
|
|
out.append(' ');
|
|
|
|
out.append(line);
|
|
|
|
}
|
2012-04-24 18:29:09 +02:00
|
|
|
}
|
2012-04-02 13:46:53 +02:00
|
|
|
|
|
|
|
out = out.simplified();
|
2012-04-24 18:29:09 +02:00
|
|
|
for (int i = 1; i < out.length() - 1; ) {
|
|
|
|
if (out.at(i).isSpace()
|
|
|
|
&& !(out.at(i-1).isLetterOrNumber()
|
|
|
|
&& out.at(i+1).isLetterOrNumber()))
|
2012-04-02 13:46:53 +02:00
|
|
|
out.remove(i,1);
|
|
|
|
else
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
2012-03-16 14:06:09 +01:00
|
|
|
void tst_Preprocessor::va_args()
|
|
|
|
{
|
|
|
|
Client *client = 0; // no client.
|
|
|
|
Environment env;
|
|
|
|
|
|
|
|
Preprocessor preprocess(client, &env);
|
2012-04-19 10:35:49 +02:00
|
|
|
QByteArray preprocessed = preprocess.run(QLatin1String("<stdin>"),
|
|
|
|
"#define foo(...) int f(__VA_ARGS__);\n"
|
|
|
|
"\nfoo( )\n"
|
|
|
|
"\nfoo(int a)\n"
|
|
|
|
"\nfoo(int a,int b)\n",
|
|
|
|
true, false);
|
2012-03-16 14:06:09 +01:00
|
|
|
|
2012-03-26 15:18:01 +02:00
|
|
|
preprocessed = preprocessed.simplified();
|
|
|
|
// DUMP_OUTPUT(preprocessed);
|
2012-04-02 13:46:53 +02:00
|
|
|
QCOMPARE(simplified(preprocessed), QString("int f();int f(int a);int f(int a,int b);"));
|
2012-03-16 14:06:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void tst_Preprocessor::named_va_args()
|
|
|
|
{
|
|
|
|
Client *client = 0; // no client.
|
|
|
|
Environment env;
|
|
|
|
|
|
|
|
Preprocessor preprocess(client, &env);
|
2012-04-19 10:35:49 +02:00
|
|
|
QByteArray preprocessed = preprocess.run(QLatin1String("<stdin>"),
|
|
|
|
"\n#define foo(ARGS...) int f(ARGS);"
|
|
|
|
"\nfoo( )\n"
|
|
|
|
"\nfoo(int a)\n"
|
|
|
|
"\nfoo(int a,int b)\n",
|
|
|
|
true, false);
|
2012-03-16 14:06:09 +01:00
|
|
|
|
2012-03-26 15:18:01 +02:00
|
|
|
preprocessed = preprocessed.simplified();
|
2012-04-02 13:46:53 +02:00
|
|
|
QCOMPARE(simplified(preprocessed), QString("int f();int f(int a);int f(int a,int b);"));
|
2012-03-16 14:06:09 +01:00
|
|
|
}
|
|
|
|
|
2013-04-25 17:13:39 +02:00
|
|
|
void tst_Preprocessor::extra_va_args()
|
|
|
|
{
|
|
|
|
Client *client = 0; // no client.
|
|
|
|
Environment env;
|
|
|
|
|
|
|
|
Preprocessor preprocess(client, &env);
|
|
|
|
QByteArray preprocessed = preprocess.run(QLatin1String("<stdin>"),
|
|
|
|
"#define foo(ret, ...) ret f(__VA_ARGS__);\n"
|
|
|
|
"\nfoo(int)\n"
|
|
|
|
"\nfoo(float,int b)\n"
|
|
|
|
"\nfoo(long,int b,int c)\n",
|
|
|
|
true, false);
|
|
|
|
|
|
|
|
preprocessed = preprocessed.simplified();
|
|
|
|
QCOMPARE(simplified(preprocessed), QString("int f();float f(int b);long f(int b,int c);"));
|
|
|
|
}
|
|
|
|
|
2012-06-12 14:51:48 +02:00
|
|
|
void tst_Preprocessor::empty_macro_args()
|
2012-03-16 14:10:46 +01:00
|
|
|
{
|
|
|
|
Client *client = 0; // no client.
|
|
|
|
Environment env;
|
|
|
|
|
|
|
|
Preprocessor preprocess(client, &env);
|
2012-04-19 10:35:49 +02:00
|
|
|
QByteArray preprocessed = preprocess.run(QLatin1String("<stdin>"),
|
|
|
|
"\n#define foo(a,b) a int b;"
|
|
|
|
"\nfoo(const,cVal)\n"
|
|
|
|
"\nfoo(,Val)\n"
|
2012-06-12 14:51:48 +02:00
|
|
|
"\nfoo( ,Val2)\n"
|
|
|
|
"\nfoo(,)\n"
|
|
|
|
"\nfoo(, )\n",
|
2012-04-19 10:35:49 +02:00
|
|
|
true, false);
|
2012-03-16 14:10:46 +01:00
|
|
|
|
2012-03-26 15:18:01 +02:00
|
|
|
preprocessed = preprocessed.simplified();
|
|
|
|
// DUMP_OUTPUT(preprocessed);
|
2012-06-12 14:51:48 +02:00
|
|
|
QCOMPARE(simplified(preprocessed),
|
|
|
|
QString("const int cVal;int Val;int Val2;int;int;"));
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_Preprocessor::macro_args_count()
|
|
|
|
{
|
|
|
|
Environment env;
|
|
|
|
QByteArray output;
|
|
|
|
MockClient client(&env, &output);
|
|
|
|
Preprocessor preprocess(&client, &env);
|
|
|
|
preprocess.run(QLatin1String("<stdin>"),
|
|
|
|
"#define foo(a,b) a int b;\n"
|
|
|
|
"foo(const,cVal)\n"
|
|
|
|
"foo(, i)\n"
|
|
|
|
"foo(,Val)\n"
|
|
|
|
"foo( ,Val2)\n"
|
|
|
|
"foo(,)\n"
|
|
|
|
"foo(, )\n"
|
|
|
|
"#define bar(a)\n"
|
|
|
|
"bar()\n"
|
|
|
|
"bar(i)\n",
|
|
|
|
true, false);
|
|
|
|
|
|
|
|
QCOMPARE(client.macroArgsCount(),
|
|
|
|
QList<int>() << 2 // foo(const,cVal)
|
|
|
|
<< 2 // foo(, i)
|
|
|
|
<< 2 // foo(,Val)
|
|
|
|
<< 2 // foo( , Val2)
|
|
|
|
<< 2 // foo(,)
|
|
|
|
<< 2 // foo(, )
|
|
|
|
<< 1 // bar()
|
|
|
|
<< 1 // bar(i)
|
|
|
|
);
|
|
|
|
|
2012-03-16 14:10:46 +01:00
|
|
|
}
|
|
|
|
|
2012-03-26 15:18:01 +02:00
|
|
|
void tst_Preprocessor::invalid_param_count()
|
2012-03-16 14:22:17 +01:00
|
|
|
{
|
2012-04-02 13:46:53 +02:00
|
|
|
Environment env;
|
2012-06-12 15:59:07 +02:00
|
|
|
QByteArray output;
|
|
|
|
MockClient client(&env, &output);
|
|
|
|
Preprocessor preprocess(&client, &env);
|
|
|
|
// The following are illegal, but shouldn't crash the preprocessor.
|
|
|
|
preprocess.run(QLatin1String("<stdin>"),
|
|
|
|
"\n#define foo(a,b) int f(a,b);"
|
|
|
|
"\n#define ARGS(t) t a,t b"
|
|
|
|
"\nfoo(ARGS(int))"
|
|
|
|
"\nfoo()"
|
|
|
|
"\nfoo(int a, int b, int c)",
|
|
|
|
true, false);
|
2012-04-02 13:46:53 +02:00
|
|
|
|
2012-06-12 15:59:07 +02:00
|
|
|
// Output is not that relevant but check that nothing triggered expansion.
|
|
|
|
QCOMPARE(client.macroArgsCount(), QList<int>());
|
2012-04-02 13:46:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void tst_Preprocessor::macro_uses()
|
|
|
|
{
|
|
|
|
QByteArray buffer = QByteArray("\n#define FOO 8"
|
|
|
|
"\n#define BAR 9"
|
|
|
|
"\nvoid test(){"
|
|
|
|
"\n\tint x=FOO;"
|
|
|
|
"\n\tint y=BAR;"
|
|
|
|
"\n}");
|
|
|
|
|
|
|
|
QByteArray output;
|
|
|
|
Environment env;
|
|
|
|
MockClient client(&env, &output);
|
|
|
|
|
|
|
|
Preprocessor preprocess(&client, &env);
|
2012-04-19 10:35:49 +02:00
|
|
|
QByteArray preprocessed = preprocess.run(QLatin1String("<stdin>"), buffer);
|
2012-04-02 13:46:53 +02:00
|
|
|
QCOMPARE(simplified(preprocessed), QString("void test(){int x=8;int y=9;}"));
|
|
|
|
QCOMPARE(client.expandedMacros(), QList<QByteArray>() << QByteArray("FOO") << QByteArray("BAR"));
|
|
|
|
QCOMPARE(client.expandedMacrosOffset(), QList<unsigned>() << buffer.indexOf("FOO;") << buffer.indexOf("BAR;"));
|
2012-04-02 14:57:13 +02:00
|
|
|
QCOMPARE(client.definedMacros(), QList<QByteArray>() << QByteArray("FOO") << QByteArray("BAR"));
|
|
|
|
QCOMPARE(client.definedMacrosLine(), QList<unsigned>() << 2 << 3);
|
2012-04-02 13:46:53 +02:00
|
|
|
}
|
|
|
|
|
2012-05-29 12:37:55 +02:00
|
|
|
void tst_Preprocessor::macro_uses_lines()
|
|
|
|
{
|
|
|
|
QByteArray buffer("#define FOO\n"
|
|
|
|
"FOO\n"
|
|
|
|
"\n"
|
|
|
|
"#define HEADER <test>\n"
|
|
|
|
"#include HEADER\n"
|
|
|
|
"\n"
|
|
|
|
"#define DECLARE(C, V) struct C {}; C V;\n"
|
|
|
|
"#define ABC X\n"
|
|
|
|
"DECLARE(Test, test)\n"
|
|
|
|
"\n"
|
|
|
|
"int abc;\n"
|
|
|
|
"#define NOTHING(C)\n"
|
|
|
|
"NOTHING(abc)\n"
|
|
|
|
"\n"
|
|
|
|
"#define ENABLE(FEATURE) (defined ENABLE_##FEATURE && ENABLE_##FEATURE)\n"
|
|
|
|
"#define ENABLE_COOL 1\n"
|
|
|
|
"void fill();\n"
|
|
|
|
"#if ENABLE(COOL)\n"
|
|
|
|
"class Cool {};\n"
|
|
|
|
"#endif\n"
|
2012-05-29 15:27:56 +02:00
|
|
|
"int cool = ENABLE_COOL;\n"
|
|
|
|
"#define OTHER_ENABLE(FEATURE) ENABLE(FEATURE)\n"
|
|
|
|
"#define MORE(LESS) FOO ENABLE(LESS)\n");
|
2012-05-29 12:37:55 +02:00
|
|
|
|
|
|
|
QByteArray output;
|
|
|
|
Environment env;
|
|
|
|
MockClient client(&env, &output);
|
|
|
|
Preprocessor preprocess(&client, &env);
|
|
|
|
preprocess.run(QLatin1String("<stdin>"), buffer);
|
|
|
|
|
2012-05-29 15:27:56 +02:00
|
|
|
QCOMPARE(client.macroUsesLine().value("FOO"), QList<unsigned>() << 2U << 23U);
|
|
|
|
QCOMPARE(client.macroUsesLine().value("HEADER"), QList<unsigned>() << 5U);
|
|
|
|
QCOMPARE(client.macroUsesLine().value("DECLARE"), QList<unsigned>() << 9U);
|
|
|
|
QCOMPARE(client.macroUsesLine().value("NOTHING"), QList<unsigned>() << 13U);
|
|
|
|
QCOMPARE(client.macroUsesLine().value("ENABLE"), QList<unsigned>() << 18U << 22U << 23U);
|
|
|
|
QCOMPARE(client.macroUsesLine().value("ENABLE_COOL"), QList<unsigned>() << 21U);
|
2014-02-22 21:34:07 +02:00
|
|
|
QCOMPARE(client.definitionsResolvedFromLines().value("ENABLE_COOL"), QList<unsigned>() << 18U);
|
2012-05-29 12:37:55 +02:00
|
|
|
QCOMPARE(client.expandedMacrosOffset(), QList<unsigned>()
|
2012-05-29 15:27:56 +02:00
|
|
|
<< buffer.lastIndexOf("FOO\n")
|
2012-05-29 12:37:55 +02:00
|
|
|
<< buffer.lastIndexOf("HEADER")
|
|
|
|
<< buffer.lastIndexOf("DECLARE")
|
|
|
|
<< buffer.lastIndexOf("NOTHING")
|
|
|
|
<< buffer.lastIndexOf("ENABLE(COOL)")
|
2012-05-29 15:27:56 +02:00
|
|
|
<< buffer.lastIndexOf("ENABLE_COOL")
|
|
|
|
<< buffer.lastIndexOf("ENABLE(FEATURE)")
|
|
|
|
<< buffer.lastIndexOf("FOO ")
|
|
|
|
<< buffer.lastIndexOf("ENABLE(LESS)"));
|
2012-05-29 12:37:55 +02:00
|
|
|
}
|
|
|
|
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
void tst_Preprocessor::multitokens_argument_data()
|
2012-03-16 15:16:06 +01:00
|
|
|
{
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
QTest::addColumn<QByteArray>("input");
|
|
|
|
QTest::addColumn<QByteArray>("output");
|
|
|
|
|
2014-01-13 22:57:32 +02:00
|
|
|
QTest::newRow("case 1") << _(
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
"#define foo(ARGS) int f(ARGS)\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
"foo(int a);\n"
|
|
|
|
) << _(
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"# expansion begin 30,3 ~3 2:4 2:8 ~1\n"
|
|
|
|
"int f(int a)\n"
|
|
|
|
"# expansion end\n"
|
|
|
|
"# 2 \"<stdin>\"\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
" ;\n"
|
|
|
|
);
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
|
2014-01-13 22:57:32 +02:00
|
|
|
QTest::newRow("case 2") << _(
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
"#define foo(ARGS) int f(ARGS)\n"
|
|
|
|
"foo(int \n"
|
2014-01-13 22:57:32 +02:00
|
|
|
" a);\n"
|
|
|
|
) << _(
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"# expansion begin 30,3 ~3 2:4 3:4 ~1\n"
|
|
|
|
"int f(int a)\n"
|
|
|
|
"# expansion end\n"
|
|
|
|
"# 3 \"<stdin>\"\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
" ;\n"
|
|
|
|
);
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
|
2014-01-13 22:57:32 +02:00
|
|
|
QTest::newRow("case 3") << _(
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
"#define foo(ARGS) int f(ARGS)\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
"foo(int a = 0);\n"
|
|
|
|
) << _(
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"# expansion begin 30,3 ~3 2:4 2:8 2:10 2:12 ~1\n"
|
|
|
|
"int f(int a = 0)\n"
|
|
|
|
"# expansion end\n"
|
|
|
|
"# 2 \"<stdin>\"\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
" ;\n"
|
|
|
|
);
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
|
2014-01-13 22:57:32 +02:00
|
|
|
QTest::newRow("case 4") << _(
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
"#define foo(X) int f(X = 0)\n"
|
|
|
|
"foo(int \n"
|
2014-01-13 22:57:32 +02:00
|
|
|
" a);\n"
|
|
|
|
) << _(
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"# expansion begin 28,3 ~3 2:4 3:4 ~3\n"
|
|
|
|
"int f(int a = 0)\n"
|
|
|
|
"# expansion end\n"
|
|
|
|
"# 3 \"<stdin>\"\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
" ;\n"
|
|
|
|
);
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void tst_Preprocessor::multitokens_argument()
|
|
|
|
{
|
|
|
|
compare_input_output();
|
2012-03-16 15:16:06 +01:00
|
|
|
}
|
|
|
|
|
2012-04-02 08:46:56 +02:00
|
|
|
void tst_Preprocessor::objmacro_expanding_as_fnmacro_notification()
|
|
|
|
{
|
|
|
|
QByteArray output;
|
|
|
|
Environment env;
|
|
|
|
MockClient client(&env, &output);
|
|
|
|
|
|
|
|
Preprocessor preprocess(&client, &env);
|
2012-04-19 10:35:49 +02:00
|
|
|
QByteArray preprocessed = preprocess.run(QLatin1String("<stdin>"),
|
2012-04-02 08:46:56 +02:00
|
|
|
QByteArray("\n#define bar(a,b) a + b"
|
|
|
|
"\n#define foo bar"
|
|
|
|
"\nfoo(1, 2)\n"));
|
|
|
|
|
|
|
|
QVERIFY(client.expandedMacros() == (QList<QByteArray>() << QByteArray("foo")));
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_Preprocessor::macro_arguments_notificatin()
|
|
|
|
{
|
|
|
|
QByteArray output;
|
|
|
|
Environment env;
|
|
|
|
MockClient client(&env, &output);
|
|
|
|
|
|
|
|
Preprocessor preprocess(&client, &env);
|
2012-04-19 10:35:49 +02:00
|
|
|
QByteArray preprocessed = preprocess.run(QLatin1String("<stdin>"),
|
2012-04-02 08:46:56 +02:00
|
|
|
QByteArray("\n#define foo(a,b) a + b"
|
|
|
|
"\n#define arg(a) a"
|
|
|
|
"\n#define value 2"
|
|
|
|
"\nfoo(arg(1), value)\n"));
|
|
|
|
|
|
|
|
QVERIFY(client.expandedMacros() == (QList<QByteArray>() << QByteArray("foo")
|
|
|
|
<< QByteArray("arg")
|
|
|
|
<< QByteArray("value")));
|
|
|
|
}
|
|
|
|
|
2009-03-03 16:32:08 +01:00
|
|
|
void tst_Preprocessor::unfinished_function_like_macro_call()
|
|
|
|
{
|
|
|
|
Client *client = 0; // no client.
|
|
|
|
Environment env;
|
|
|
|
|
|
|
|
Preprocessor preprocess(client, &env);
|
2012-04-19 10:35:49 +02:00
|
|
|
QByteArray preprocessed = preprocess.run(QLatin1String("<stdin>"),
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
QByteArray("\n"
|
|
|
|
"#define foo(a,b) a + b\n"
|
|
|
|
"foo(1, 2\n"));
|
|
|
|
QByteArray expected__("# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"# expansion begin 24,3 3:4 ~1 3:7\n"
|
|
|
|
"1 + 2\n"
|
|
|
|
"# expansion end\n"
|
|
|
|
"# 4 \"<stdin>\"\n");
|
|
|
|
|
2012-03-30 13:01:32 +02:00
|
|
|
// DUMP_OUTPUT(preprocessed);
|
2012-03-26 15:18:01 +02:00
|
|
|
QCOMPARE(preprocessed, expected__);
|
2009-03-03 16:32:08 +01:00
|
|
|
}
|
|
|
|
|
2010-02-10 11:04:31 +01:00
|
|
|
void tst_Preprocessor::nasty_macro_expansion()
|
|
|
|
{
|
|
|
|
QByteArray input("\n"
|
|
|
|
"#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))\n"
|
|
|
|
"#define is_power_of_two(x) ( !((x) & ((x)-1)) )\n"
|
|
|
|
"#define low_bit_mask(x) ( ((x)-1) & ~(x) )\n"
|
|
|
|
"#define is_valid_mask(x) is_power_of_two(1LU + (x) + low_bit_mask(x))\n"
|
|
|
|
"#define compile_ffs2(__x) \\\n"
|
|
|
|
" __builtin_choose_expr(((__x) & 0x1), 0, 1)\n"
|
|
|
|
"#define compile_ffs4(__x) \\\n"
|
|
|
|
" __builtin_choose_expr(((__x) & 0x3), \\\n"
|
|
|
|
" (compile_ffs2((__x))), \\\n"
|
|
|
|
" (compile_ffs2((__x) >> 2) + 2))\n"
|
|
|
|
"#define compile_ffs8(__x) \\\n"
|
|
|
|
" __builtin_choose_expr(((__x) & 0xf), \\\n"
|
|
|
|
" (compile_ffs4((__x))), \\\n"
|
|
|
|
" (compile_ffs4((__x) >> 4) + 4))\n"
|
|
|
|
"#define compile_ffs16(__x) \\\n"
|
|
|
|
" __builtin_choose_expr(((__x) & 0xff), \\\n"
|
|
|
|
" (compile_ffs8((__x))), \\\n"
|
|
|
|
" (compile_ffs8((__x) >> 8) + 8))\n"
|
|
|
|
"#define compile_ffs32(__x) \\\n"
|
|
|
|
" __builtin_choose_expr(((__x) & 0xffff), \\\n"
|
|
|
|
" (compile_ffs16((__x))), \\\n"
|
|
|
|
" (compile_ffs16((__x) >> 16) + 16))\n"
|
|
|
|
"#define FIELD_CHECK(__mask, __type) \\\n"
|
|
|
|
" BUILD_BUG_ON(!(__mask) || \\\n"
|
|
|
|
" !is_valid_mask(__mask) || \\\n"
|
|
|
|
" (__mask) != (__type)(__mask)) \\\n"
|
|
|
|
"\n"
|
|
|
|
"#define FIELD32(__mask) \\\n"
|
|
|
|
"({ \\\n"
|
|
|
|
" FIELD_CHECK(__mask, u32); \\\n"
|
|
|
|
" (struct rt2x00_field32) { \\\n"
|
|
|
|
" compile_ffs32(__mask), (__mask) \\\n"
|
|
|
|
" }; \\\n"
|
|
|
|
"})\n"
|
|
|
|
"#define BBPCSR 0x00f0\n"
|
|
|
|
"#define BBPCSR_BUSY FIELD32(0x00008000)\n"
|
|
|
|
"#define WAIT_FOR_BBP(__dev, __reg) \\\n"
|
|
|
|
" rt2x00pci_regbusy_read((__dev), BBPCSR, BBPCSR_BUSY, (__reg))\n"
|
|
|
|
"if (WAIT_FOR_BBP(rt2x00dev, ®)) {}\n"
|
|
|
|
);
|
|
|
|
|
|
|
|
Client *client = 0; // no client.
|
|
|
|
Environment env;
|
|
|
|
|
|
|
|
Preprocessor preprocess(client, &env);
|
2012-04-19 10:35:49 +02:00
|
|
|
QByteArray preprocessed = preprocess.run(QLatin1String("<stdin>"), input);
|
2010-02-10 11:04:31 +01:00
|
|
|
|
|
|
|
QVERIFY(!preprocessed.contains("FIELD32"));
|
|
|
|
}
|
|
|
|
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
void tst_Preprocessor::glib_attribute()
|
2012-02-24 13:06:21 +01:00
|
|
|
{
|
|
|
|
Environment env;
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
Preprocessor preprocess(0, &env);
|
2012-04-19 10:35:49 +02:00
|
|
|
QByteArray preprocessed = preprocess.run(
|
2012-02-24 13:06:21 +01:00
|
|
|
QLatin1String("<stdin>"),
|
|
|
|
QByteArray("\n"
|
|
|
|
"# define _GLIBCXX_VISIBILITY(V) __attribute__ ((__visibility__ (#V)))\n"
|
|
|
|
"namespace std _GLIBCXX_VISIBILITY(default) {\n"
|
|
|
|
"}\n"
|
|
|
|
));
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
const QByteArray result____ =
|
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
2012-03-26 15:18:01 +02:00
|
|
|
"namespace std\n"
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
"# expansion begin 85,19 ~9\n"
|
|
|
|
"__attribute__ ((__visibility__ (\"default\")))\n"
|
|
|
|
"# expansion end\n"
|
2012-03-13 11:50:56 +01:00
|
|
|
"# 3 \"<stdin>\"\n"
|
|
|
|
" {\n"
|
2012-03-26 15:18:01 +02:00
|
|
|
"}\n";
|
|
|
|
|
2012-03-30 13:01:32 +02:00
|
|
|
// DUMP_OUTPUT(preprocessed);
|
2012-03-26 15:18:01 +02:00
|
|
|
QCOMPARE(preprocessed, result____);
|
2013-11-29 10:53:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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"
|
2013-12-02 15:47:36 +01:00
|
|
|
"const char *f = \"some-file.c\"\n";
|
2013-11-29 10:53:45 +01:00
|
|
|
|
|
|
|
QCOMPARE(preprocessed, result____);
|
2012-03-26 15:18:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void tst_Preprocessor::comparisons_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<QString>("infile");
|
|
|
|
QTest::addColumn<QString>("outfile");
|
|
|
|
QTest::addColumn<QString>("errorfile");
|
|
|
|
|
|
|
|
QTest::newRow("do nothing") << "noPP.1.cpp" << "noPP.1.cpp" << "";
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
QTest::newRow("no PP 2") << "noPP.2.cpp" << "noPP.2.cpp" << "";
|
2012-04-24 18:29:09 +02:00
|
|
|
QTest::newRow("identifier-expansion 1")
|
|
|
|
<< "identifier-expansion.1.cpp" << "identifier-expansion.1.out.cpp" << "";
|
|
|
|
QTest::newRow("identifier-expansion 2")
|
|
|
|
<< "identifier-expansion.2.cpp" << "identifier-expansion.2.out.cpp" << "";
|
|
|
|
QTest::newRow("identifier-expansion 3")
|
|
|
|
<< "identifier-expansion.3.cpp" << "identifier-expansion.3.out.cpp" << "";
|
|
|
|
QTest::newRow("identifier-expansion 4")
|
|
|
|
<< "identifier-expansion.4.cpp" << "identifier-expansion.4.out.cpp" << "";
|
|
|
|
QTest::newRow("identifier-expansion 5")
|
|
|
|
<< "identifier-expansion.5.cpp" << "identifier-expansion.5.out.cpp" << "";
|
2012-04-27 16:46:57 +02:00
|
|
|
QTest::newRow("reserved 1")
|
|
|
|
<< "reserved.1.cpp" << "reserved.1.out.cpp" << "";
|
|
|
|
QTest::newRow("recursive 1")
|
|
|
|
<< "recursive.1.cpp" << "recursive.1.out.cpp" << "";
|
2013-06-10 15:12:17 +02:00
|
|
|
QTest::newRow("recursive 2")
|
|
|
|
<< "recursive.2.cpp" << "recursive.2.out.cpp" << "";
|
2012-04-27 16:46:57 +02:00
|
|
|
QTest::newRow("macro_pounder_fn")
|
|
|
|
<< "macro_pounder_fn.c" << "" << "";
|
|
|
|
QTest::newRow("macro_expand")
|
|
|
|
<< "macro_expand.c" << "macro_expand.out.c" << "";
|
2012-05-15 17:39:13 +02:00
|
|
|
QTest::newRow("macro_expand_1")
|
|
|
|
<< "macro_expand_1.cpp" << "macro_expand_1.out.cpp" << "";
|
2012-04-27 16:46:57 +02:00
|
|
|
QTest::newRow("macro-test")
|
|
|
|
<< "macro-test.cpp" << "macro-test.out.cpp" << "";
|
|
|
|
QTest::newRow("empty-macro")
|
|
|
|
<< "empty-macro.cpp" << "empty-macro.out.cpp" << "";
|
|
|
|
QTest::newRow("empty-macro 2")
|
|
|
|
<< "empty-macro.2.cpp" << "empty-macro.2.out.cpp" << "";
|
2012-04-27 17:11:48 +02:00
|
|
|
QTest::newRow("poundpound 1")
|
|
|
|
<< "poundpound.1.cpp" << "poundpound.1.out.cpp" << "";
|
2012-03-26 15:18:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void tst_Preprocessor::comparisons()
|
|
|
|
{
|
|
|
|
QFETCH(QString, infile);
|
|
|
|
QFETCH(QString, outfile);
|
|
|
|
QFETCH(QString, errorfile);
|
|
|
|
|
|
|
|
QByteArray errors;
|
2012-03-30 13:01:32 +02:00
|
|
|
QByteArray preprocessed = preprocess(infile, &errors, infile == outfile);
|
2012-03-26 15:18:01 +02:00
|
|
|
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
|
2012-04-27 16:46:57 +02:00
|
|
|
// DUMP_OUTPUT(preprocessed);
|
2012-03-26 15:18:01 +02:00
|
|
|
|
|
|
|
if (!outfile.isEmpty()) {
|
2012-04-27 16:46:57 +02:00
|
|
|
// These weird underscores are here to make the name as long as
|
|
|
|
// "preprocessed", so the QCOMPARE error messages are nicely aligned.
|
|
|
|
QByteArray output____ = loadSource("data/" + outfile);
|
2012-03-26 15:18:01 +02:00
|
|
|
// QCOMPARE(preprocessed, output____);
|
2012-04-27 16:46:57 +02:00
|
|
|
QCOMPARE(QString::fromUtf8(preprocessed.constData()),
|
|
|
|
QString::fromUtf8(output____.constData()));
|
2012-03-26 15:18:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!errorfile.isEmpty()) {
|
2012-04-27 16:46:57 +02:00
|
|
|
QByteArray errorFileContents = loadSource("data/" + errorfile);
|
|
|
|
QCOMPARE(QString::fromUtf8(errors.constData()),
|
|
|
|
QString::fromUtf8(errorFileContents.constData()));
|
2012-03-26 15:18:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_Preprocessor::blockSkipping()
|
|
|
|
{
|
|
|
|
QByteArray output;
|
|
|
|
Environment env;
|
|
|
|
MockClient client(&env, &output);
|
|
|
|
Preprocessor pp(&client, &env);
|
2012-04-19 10:35:49 +02:00
|
|
|
/*QByteArray preprocessed =*/ pp.run(
|
2012-03-26 15:18:01 +02:00
|
|
|
QLatin1String("<stdin>"),
|
|
|
|
QByteArray("#if 0\n"
|
|
|
|
"\n"
|
|
|
|
"int yes;\n"
|
|
|
|
"\n"
|
|
|
|
"#elif 0\n"
|
|
|
|
"\n"
|
|
|
|
"int no;\n"
|
|
|
|
"\n"
|
|
|
|
"#else // foobar\n"
|
|
|
|
"\n"
|
|
|
|
"void also_not;\n"
|
|
|
|
"\n"
|
|
|
|
"#endif\n"
|
|
|
|
));
|
2012-03-13 11:50:56 +01:00
|
|
|
|
2012-03-26 15:18:01 +02:00
|
|
|
QList<MockClient::Block> blocks = client.skippedBlocks();
|
|
|
|
QCOMPARE(blocks.size(), 1);
|
|
|
|
MockClient::Block b = blocks.at(0);
|
|
|
|
QCOMPARE(b.start, 6U);
|
|
|
|
QCOMPARE(b.end, 34U);
|
2012-02-24 13:06:21 +01:00
|
|
|
}
|
|
|
|
|
2012-03-29 17:14:42 +02:00
|
|
|
void tst_Preprocessor::includes_1()
|
|
|
|
{
|
|
|
|
QByteArray output;
|
|
|
|
Environment env;
|
|
|
|
MockClient client(&env, &output);
|
|
|
|
Preprocessor pp(&client, &env);
|
2012-04-19 10:35:49 +02:00
|
|
|
/*QByteArray preprocessed =*/ pp.run(
|
2012-03-29 17:14:42 +02:00
|
|
|
QLatin1String("<stdin>"),
|
|
|
|
QByteArray("#define FOO <foo.h>\n"
|
|
|
|
"#define BAR \"bar.h\"\n"
|
|
|
|
"\n"
|
|
|
|
"#include FOO\n"
|
|
|
|
"#include BAR\n"
|
|
|
|
"\n"
|
|
|
|
"#include <zoo.h>\n"
|
|
|
|
"#include \"mooze.h\"\n"
|
|
|
|
));
|
|
|
|
|
|
|
|
QList<Include> incs = client.recordedIncludes();
|
|
|
|
// qDebug()<<incs;
|
|
|
|
QCOMPARE(incs.size(), 4);
|
|
|
|
QCOMPARE(incs.at(0).fileName, QLatin1String("foo.h"));
|
|
|
|
QCOMPARE(incs.at(0).type, Client::IncludeGlobal);
|
|
|
|
QCOMPARE(incs.at(0).line, 4U);
|
|
|
|
QCOMPARE(incs.at(1).fileName, QLatin1String("bar.h"));
|
|
|
|
QCOMPARE(incs.at(1).type, Client::IncludeLocal);
|
|
|
|
QCOMPARE(incs.at(1).line, 5U);
|
|
|
|
QCOMPARE(incs.at(2).fileName, QLatin1String("zoo.h"));
|
|
|
|
QCOMPARE(incs.at(2).type, Client::IncludeGlobal);
|
|
|
|
QCOMPARE(incs.at(2).line, 7U);
|
|
|
|
QCOMPARE(incs.at(3).fileName, QLatin1String("mooze.h"));
|
|
|
|
QCOMPARE(incs.at(3).type, Client::IncludeLocal);
|
|
|
|
QCOMPARE(incs.at(3).line, 8U);
|
|
|
|
}
|
|
|
|
|
2012-04-19 15:19:38 +02:00
|
|
|
void tst_Preprocessor::defined()
|
|
|
|
{
|
|
|
|
QFETCH(bool, xdefined);
|
|
|
|
QFETCH(bool, ydefined);
|
|
|
|
QFETCH(QString, input);
|
|
|
|
QByteArray output;
|
|
|
|
Environment env;
|
|
|
|
MockClient client(&env, &output);
|
|
|
|
Preprocessor pp(&client, &env);
|
|
|
|
pp.run(QLatin1String("<stdin>"), input.toLatin1(), false, true);
|
|
|
|
QList<QByteArray> expected;
|
|
|
|
if (xdefined)
|
|
|
|
expected.append("X");
|
|
|
|
if (ydefined)
|
|
|
|
expected.append("Y");
|
|
|
|
if (client.definedMacros() != expected)
|
|
|
|
qWarning() << "\nSource: " << input.replace('\n', " ");
|
|
|
|
QCOMPARE(client.definedMacros(), expected);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_Preprocessor::defined_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<bool>("xdefined");
|
|
|
|
QTest::addColumn<bool>("ydefined");
|
|
|
|
QTest::addColumn<QString>("input");
|
|
|
|
|
|
|
|
QTest::newRow("1a") << true << true <<
|
|
|
|
"#define X\n#if defined(X)\n#define Y\n#endif";
|
|
|
|
QTest::newRow("1b") << true << true <<
|
|
|
|
"#define X\n#if defined X \n#define Y\n#endif";
|
|
|
|
QTest::newRow("1c") << true << true <<
|
|
|
|
"#define X\n#ifdef X \n#define Y\n#endif";
|
|
|
|
|
|
|
|
QTest::newRow("2a") << false << false <<
|
|
|
|
"#if defined(X)\n#define Y\n#endif";
|
|
|
|
QTest::newRow("2b") << false << false <<
|
|
|
|
"#if defined X \n#define Y\n#endif";
|
|
|
|
QTest::newRow("2c") << false << false <<
|
|
|
|
"#ifdef X \n#define Y\n#endif";
|
|
|
|
|
|
|
|
QTest::newRow("3a") << true << false <<
|
|
|
|
"#define X\n#if !defined(X)\n#define Y\n#endif";
|
|
|
|
QTest::newRow("3b") << true << false <<
|
|
|
|
"#define X\n#if !defined X \n#define Y\n#endif";
|
|
|
|
QTest::newRow("3c") << true << false <<
|
|
|
|
"#define X\n#ifndef X \n#define Y\n#endif";
|
|
|
|
|
|
|
|
QTest::newRow("4a") << false << true <<
|
|
|
|
"#if !defined(X)\n#define Y\n#endif";
|
|
|
|
QTest::newRow("4b") << false << true <<
|
|
|
|
"#if !defined X \n#define Y\n#endif";
|
|
|
|
QTest::newRow("4c") << false << true <<
|
|
|
|
"#ifndef X \n#define Y\n#endif";
|
2012-04-24 18:50:22 +02:00
|
|
|
|
|
|
|
QTest::newRow("5a") << false << false <<
|
|
|
|
"#if !defined(X) && (defined(Y))\n"
|
|
|
|
"#define X\n"
|
|
|
|
"#endif\n";
|
|
|
|
QTest::newRow("5b") << false << false <<
|
|
|
|
"#if !defined(X) && defined(Y)\n"
|
|
|
|
"#define X\n"
|
|
|
|
"#endif\n";
|
|
|
|
QTest::newRow("5c") << false << false <<
|
|
|
|
"#if !defined(X) && 0"
|
|
|
|
"#define X\n"
|
|
|
|
"#endif\n";
|
|
|
|
QTest::newRow("5d") << false << false <<
|
|
|
|
"#if (!defined(X)) && defined(Y)\n"
|
|
|
|
"#define X\n"
|
|
|
|
"#endif\n";
|
|
|
|
QTest::newRow("5d") << false << false <<
|
|
|
|
"#if (define(Y))\n"
|
|
|
|
"#define X\n"
|
|
|
|
"#endif\n";
|
2012-04-25 12:30:48 +02:00
|
|
|
|
|
|
|
QTest::newRow("6a") << true << true <<
|
|
|
|
"#define X 0x040500\n"
|
|
|
|
"#if X > 0x040000\n"
|
|
|
|
"#define Y 1\n"
|
|
|
|
"#endif\n";
|
|
|
|
QTest::newRow("6b") << true << true <<
|
|
|
|
"#define X 0x040500\n"
|
|
|
|
"#if X >= 0x040000\n"
|
|
|
|
"#define Y 1\n"
|
|
|
|
"#endif\n";
|
|
|
|
QTest::newRow("6c") << true << false <<
|
|
|
|
"#define X 0x040500\n"
|
|
|
|
"#if X == 0x040000\n"
|
|
|
|
"#define Y 1\n"
|
|
|
|
"#endif\n";
|
|
|
|
QTest::newRow("6d") << true << true <<
|
|
|
|
"#define X 0x040500\n"
|
|
|
|
"#if X == 0x040500\n"
|
|
|
|
"#define Y 1\n"
|
|
|
|
"#endif\n";
|
|
|
|
QTest::newRow("6e") << true << false <<
|
|
|
|
"#define X 0x040500\n"
|
|
|
|
"#if X < 0x040000\n"
|
|
|
|
"#define Y 1\n"
|
|
|
|
"#endif\n";
|
|
|
|
QTest::newRow("6f") << true << false <<
|
|
|
|
"#define X 0x040500\n"
|
|
|
|
"#if X <= 0x040000\n"
|
|
|
|
"#define Y 1\n"
|
|
|
|
"#endif\n";
|
2012-05-29 14:33:56 +02:00
|
|
|
|
|
|
|
QTest::newRow("incomplete defined 1") << true << true <<
|
|
|
|
"#define X 0x040500\n"
|
|
|
|
"#if defined(X\n"
|
|
|
|
"#define Y 1\n"
|
|
|
|
"#endif\n";
|
|
|
|
QTest::newRow("incomplete defined 2") << false << false <<
|
|
|
|
"#if defined(X\n"
|
|
|
|
"#define Y 1\n"
|
|
|
|
"#endif\n";
|
|
|
|
QTest::newRow("complete defined 1") << true << true <<
|
|
|
|
"#define X 0x040500\n"
|
|
|
|
"#if defined(X )\n"
|
|
|
|
"#define Y 1\n"
|
|
|
|
"#endif\n";
|
|
|
|
QTest::newRow("complete defined 2") << true << true <<
|
|
|
|
"#define X 0x040500\n"
|
|
|
|
"#if defined(X/*xxx*/)\n"
|
|
|
|
"#define Y 1\n"
|
|
|
|
"#endif\n";
|
2012-04-19 15:19:38 +02:00
|
|
|
}
|
|
|
|
|
2014-02-20 21:39:34 +02:00
|
|
|
void tst_Preprocessor::defined_usage()
|
|
|
|
{
|
|
|
|
QByteArray output;
|
|
|
|
Environment env;
|
|
|
|
MockClient client(&env, &output);
|
|
|
|
Preprocessor pp(&client, &env);
|
|
|
|
QByteArray source =
|
|
|
|
"#define X\n"
|
|
|
|
"#define Y\n"
|
|
|
|
"#ifdef X\n"
|
|
|
|
"#endif\n"
|
|
|
|
"#ifdef Y\n"
|
|
|
|
"#endif\n"
|
|
|
|
"#ifndef X\n"
|
|
|
|
"#endif\n"
|
|
|
|
"#ifndef Y\n"
|
|
|
|
"#endif\n"
|
|
|
|
"#ifdef ABSENT\n"
|
|
|
|
"#endif\n"
|
|
|
|
"#ifndef ABSENT2\n"
|
|
|
|
"#endif\n"
|
2014-02-22 21:34:07 +02:00
|
|
|
"#if defined(ABSENT3)\n"
|
|
|
|
"#endif\n"
|
|
|
|
"#if defined(X)\n"
|
|
|
|
"#endif\n"
|
|
|
|
"#if defined(X) || defined(Y)\n"
|
|
|
|
"#endif\n"
|
2014-02-20 21:39:34 +02:00
|
|
|
;
|
|
|
|
pp.run(QLatin1String("<stdin>"), source);
|
|
|
|
QHash<QByteArray, QList<unsigned> > definitionsResolvedFromLines =
|
|
|
|
client.definitionsResolvedFromLines();
|
2014-02-22 21:34:07 +02:00
|
|
|
QCOMPARE(definitionsResolvedFromLines["X"], QList<unsigned>() << 3 << 7 << 17 << 19);
|
|
|
|
QCOMPARE(definitionsResolvedFromLines["Y"], QList<unsigned>() << 5 << 9 << 19);
|
|
|
|
QCOMPARE(client.unresolvedDefines(), QSet<QByteArray>() << "ABSENT" << "ABSENT2" << "ABSENT3");
|
2014-02-20 21:39:34 +02:00
|
|
|
}
|
|
|
|
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
void tst_Preprocessor::dont_eagerly_expand_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<QByteArray>("input");
|
|
|
|
QTest::addColumn<QByteArray>("output");
|
|
|
|
|
|
|
|
// Expansion must be processed upon invocation of the macro. Therefore a particular
|
|
|
|
// identifier within a define must not be expanded (in the case it matches an
|
|
|
|
// already known macro) during the processor directive handling, but only when
|
|
|
|
// it's actually "used". Naturally, if it's still not replaced after an invocation
|
|
|
|
// it should then be expanded. This is consistent with clang and gcc for example.
|
|
|
|
|
2014-01-13 22:57:32 +02:00
|
|
|
QTest::newRow("case 1") << _(
|
|
|
|
"#define T int\n"
|
|
|
|
"#define FOO(T) T\n"
|
|
|
|
"FOO(double)\n"
|
|
|
|
) << _(
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"# expansion begin 31,3 3:4\n"
|
|
|
|
"double\n"
|
|
|
|
"# expansion end\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
"# 4 \"<stdin>\"\n"
|
|
|
|
);
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
|
2014-01-13 22:57:32 +02:00
|
|
|
QTest::newRow("case 2") << _(
|
|
|
|
"#define T int\n"
|
|
|
|
"#define FOO(X) T\n"
|
|
|
|
"FOO(double)\n"
|
|
|
|
) << _(
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"# expansion begin 31,3 ~1\n"
|
|
|
|
"int\n"
|
|
|
|
"# expansion end\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
"# 4 \"<stdin>\"\n"
|
|
|
|
);
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void tst_Preprocessor::dont_eagerly_expand()
|
|
|
|
{
|
|
|
|
compare_input_output();
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_Preprocessor::comments_within()
|
|
|
|
{
|
2014-01-14 22:09:04 +02:00
|
|
|
QFETCH(QByteArray, input);
|
|
|
|
QFETCH(QByteArray, without_comments);
|
|
|
|
QFETCH(QByteArray, with_comments);
|
|
|
|
|
|
|
|
Environment env;
|
|
|
|
Preprocessor preprocess(0, &env);
|
|
|
|
preprocess.setKeepComments(false);
|
|
|
|
QByteArray prep = preprocess.run(QLatin1String("<stdin>"), input);
|
|
|
|
QCOMPARE(prep.constData(), without_comments.constData());
|
|
|
|
preprocess.setKeepComments(true);
|
|
|
|
prep = preprocess.run(QLatin1String("<stdin>"), input);
|
|
|
|
QCOMPARE(prep.constData(), with_comments.constData());
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
}
|
2014-01-14 22:09:04 +02:00
|
|
|
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
void tst_Preprocessor::comments_within_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<QByteArray>("input");
|
2014-01-14 22:09:04 +02:00
|
|
|
QTest::addColumn<QByteArray>("without_comments");
|
|
|
|
QTest::addColumn<QByteArray>("with_comments");
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
|
2014-01-13 22:57:32 +02:00
|
|
|
QTest::newRow("case 1") << _(
|
|
|
|
"#define FOO int x;\n"
|
|
|
|
"\n"
|
|
|
|
" // comment\n"
|
|
|
|
" // comment\n"
|
|
|
|
" // comment\n"
|
|
|
|
" // comment\n"
|
|
|
|
"FOO\n"
|
|
|
|
"x = 10\n"
|
|
|
|
) << _(
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"# expansion begin 76,3 ~3\n"
|
|
|
|
"int x;\n"
|
|
|
|
"# expansion end\n"
|
|
|
|
"# 8 \"<stdin>\"\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
"x = 10\n"
|
2014-01-14 22:09:04 +02:00
|
|
|
) << _(
|
2014-02-01 22:10:08 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
" // comment\n"
|
|
|
|
" // comment\n"
|
|
|
|
" // comment\n"
|
|
|
|
" // comment\n"
|
|
|
|
"# expansion begin 76,3 ~3\n"
|
|
|
|
"int x;\n"
|
|
|
|
"# expansion end\n"
|
|
|
|
"# 8 \"<stdin>\"\n"
|
|
|
|
"x = 10\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
QTest::newRow("case 2") << _(
|
|
|
|
"#define FOO int x;\n"
|
|
|
|
"\n"
|
|
|
|
" /* comment\n"
|
|
|
|
" comment\n"
|
|
|
|
" comment\n"
|
|
|
|
" comment */\n"
|
|
|
|
"FOO\n"
|
|
|
|
"x = 10\n"
|
|
|
|
) << _(
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"# expansion begin 79,3 ~3\n"
|
|
|
|
"int x;\n"
|
|
|
|
"# expansion end\n"
|
|
|
|
"# 8 \"<stdin>\"\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
"x = 10\n"
|
2014-01-14 22:09:04 +02:00
|
|
|
) << _(
|
2014-02-01 22:10:08 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
" /* comment\n"
|
|
|
|
" comment\n"
|
|
|
|
" comment\n"
|
|
|
|
" comment */\n"
|
|
|
|
"# expansion begin 79,3 ~3\n"
|
|
|
|
"int x;\n"
|
|
|
|
"# expansion end\n"
|
|
|
|
"# 8 \"<stdin>\"\n"
|
|
|
|
"x = 10\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
QTest::newRow("case 3") << _(
|
|
|
|
"#define FOO int x;\n"
|
|
|
|
"\n"
|
|
|
|
" // comment\n"
|
|
|
|
" // comment\n"
|
|
|
|
" // comment\n"
|
|
|
|
" // comment\n"
|
|
|
|
"FOO\n"
|
|
|
|
"// test\n"
|
|
|
|
"// test again\n"
|
|
|
|
"x = 10\n"
|
|
|
|
) << _(
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"# expansion begin 76,3 ~3\n"
|
|
|
|
"int x;\n"
|
|
|
|
"# expansion end\n"
|
|
|
|
"# 10 \"<stdin>\"\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
"x = 10\n"
|
2014-01-14 22:09:04 +02:00
|
|
|
) << _(
|
2014-02-01 22:10:08 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
" // comment\n"
|
|
|
|
" // comment\n"
|
|
|
|
" // comment\n"
|
|
|
|
" // comment\n"
|
|
|
|
"# expansion begin 76,3 ~3\n"
|
|
|
|
"int x;\n"
|
|
|
|
"# expansion end\n"
|
|
|
|
"# 8 \"<stdin>\"\n"
|
|
|
|
"// test\n"
|
|
|
|
"// test again\n"
|
|
|
|
"x = 10\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
QTest::newRow("case 4") << _(
|
|
|
|
"#define FOO int x;\n"
|
|
|
|
"\n"
|
|
|
|
" /* comment\n"
|
|
|
|
" comment\n"
|
|
|
|
" comment\n"
|
|
|
|
" comment */\n"
|
|
|
|
"FOO\n"
|
|
|
|
"/* \n"
|
|
|
|
"*/\n"
|
|
|
|
"x = 10\n"
|
|
|
|
) << _(
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"# expansion begin 79,3 ~3\n"
|
|
|
|
"int x;\n"
|
|
|
|
"# expansion end\n"
|
|
|
|
"# 10 \"<stdin>\"\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
"x = 10\n"
|
2014-01-14 22:09:04 +02:00
|
|
|
) << _(
|
2014-02-01 22:10:08 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
" /* comment\n"
|
|
|
|
" comment\n"
|
|
|
|
" comment\n"
|
|
|
|
" comment */\n"
|
|
|
|
"# expansion begin 79,3 ~3\n"
|
|
|
|
"int x;\n"
|
|
|
|
"# expansion end\n"
|
|
|
|
"# 8 \"<stdin>\"\n"
|
|
|
|
"/* \n"
|
|
|
|
"*/\n"
|
|
|
|
"x = 10\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
QTest::newRow("case 5") << _(
|
|
|
|
"#define FOO(x, y) { (void)x; (void)y; }\n"
|
|
|
|
"\n"
|
|
|
|
"void foo() {\n"
|
|
|
|
" FOO(10,\n"
|
|
|
|
" //comment\n"
|
|
|
|
" 12\n"
|
|
|
|
"}\n"
|
|
|
|
) << _(
|
2012-08-15 16:06:22 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"void foo() {\n"
|
|
|
|
"# expansion begin 57,3 ~4 4:7 ~4 6:7 7:0 ~2\n"
|
|
|
|
"{ (void)10; (void)12}; }\n"
|
|
|
|
"# expansion end\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
"# 8 \"<stdin>\"\n"
|
2014-01-14 22:09:04 +02:00
|
|
|
) << _(
|
2014-02-01 22:10:08 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"void foo() {\n"
|
|
|
|
"# expansion begin 57,3 ~4 4:7 ~5 6:7 7:0 ~2\n"
|
|
|
|
"{ (void)10; (void)/*comment*/ 12}; }\n"
|
|
|
|
"# expansion end\n"
|
|
|
|
"# 8 \"<stdin>\"\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
QTest::newRow("case 6") << _(
|
|
|
|
"#define FOO(x, y) { (void)x; (void)y; }\n"
|
|
|
|
"\n"
|
|
|
|
"void foo() {\n"
|
|
|
|
" FOO(10,\n"
|
|
|
|
" //tricky*/comment\n"
|
|
|
|
" 12\n"
|
|
|
|
"}\n"
|
|
|
|
) << _(
|
2012-08-15 16:06:22 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"void foo() {\n"
|
|
|
|
"# expansion begin 57,3 ~4 4:7 ~4 6:7 7:0 ~2\n"
|
|
|
|
"{ (void)10; (void)12}; }\n"
|
|
|
|
"# expansion end\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
"# 8 \"<stdin>\"\n"
|
2014-01-14 22:09:04 +02:00
|
|
|
) << _(
|
2014-02-01 22:10:08 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"void foo() {\n"
|
|
|
|
"# expansion begin 57,3 ~4 4:7 ~5 6:7 7:0 ~2\n"
|
|
|
|
"{ (void)10; (void)/*tricky*|comment*/ 12}; }\n"
|
|
|
|
"# expansion end\n"
|
|
|
|
"# 8 \"<stdin>\"\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
);
|
2012-09-05 15:16:47 +02:00
|
|
|
|
2014-01-13 22:57:32 +02:00
|
|
|
QTest::newRow("case 7") << _(
|
|
|
|
"#define FOO 0 //comment\n"
|
2012-09-05 15:16:47 +02:00
|
|
|
"#define BAR (1 == FOO)\n"
|
|
|
|
"void foo() {\n"
|
|
|
|
" if (BAR) {}\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
"}\n"
|
|
|
|
) << _(
|
2012-09-05 15:16:47 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"void foo() {\n"
|
|
|
|
" if (\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
"# expansion begin 68,3 ~5\n"
|
2012-09-05 15:16:47 +02:00
|
|
|
"(1 == 0)\n"
|
|
|
|
"# expansion end\n"
|
|
|
|
"# 4 \"<stdin>\"\n"
|
|
|
|
" ) {}\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
"}\n"
|
2014-01-14 22:09:04 +02:00
|
|
|
) << _(
|
2014-02-01 22:10:08 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
2014-01-10 09:08:39 +02:00
|
|
|
" //comment\n"
|
2014-02-01 22:10:08 +02:00
|
|
|
"\n"
|
|
|
|
"void foo() {\n"
|
|
|
|
" if (\n"
|
|
|
|
"# expansion begin 68,3 ~5\n"
|
|
|
|
"(1 == 0)\n"
|
|
|
|
"# expansion end\n"
|
|
|
|
"# 4 \"<stdin>\"\n"
|
|
|
|
" ) {}\n"
|
|
|
|
"}\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
);
|
2014-01-10 09:08:39 +02:00
|
|
|
QTest::newRow("case 8") << _(
|
|
|
|
"#define FOO /* comment */ 0\n"
|
|
|
|
"FOO\n"
|
|
|
|
) << _(
|
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"# expansion begin 28,3 ~1\n"
|
|
|
|
"0\n"
|
|
|
|
"# expansion end\n"
|
|
|
|
"# 3 \"<stdin>\"\n"
|
|
|
|
) << _(
|
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
" /* comment */\n"
|
|
|
|
"# expansion begin 28,3 ~1\n"
|
|
|
|
"0\n"
|
|
|
|
"# expansion end\n"
|
|
|
|
"# 3 \"<stdin>\"\n"
|
|
|
|
);
|
|
|
|
|
|
|
|
QTest::newRow("case 9") << _(
|
|
|
|
"#define FOO /* comment1 */ /* comment2 */ 0\n"
|
|
|
|
"FOO\n"
|
|
|
|
) << _(
|
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"# expansion begin 44,3 ~1\n"
|
|
|
|
"0\n"
|
|
|
|
"# expansion end\n"
|
|
|
|
"# 3 \"<stdin>\"\n"
|
|
|
|
) << _(
|
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
" /* comment1 */ /* comment2 */\n"
|
|
|
|
"# expansion begin 44,3 ~1\n"
|
|
|
|
"0\n"
|
|
|
|
"# expansion end\n"
|
|
|
|
"# 3 \"<stdin>\"\n"
|
|
|
|
);
|
|
|
|
|
|
|
|
QTest::newRow("case 10") << _(
|
|
|
|
"#define FOO /* comment1 */ /* comment2 */ 0 /* comment3\n"
|
|
|
|
"comment4 */\n"
|
|
|
|
"FOO\n"
|
|
|
|
) << _(
|
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"# expansion begin 70,3 ~1\n"
|
|
|
|
"0\n"
|
|
|
|
"# expansion end\n"
|
|
|
|
"# 4 \"<stdin>\"\n"
|
|
|
|
) << _(
|
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
" /* comment1 */ /* comment2 */ /* comment3\n"
|
|
|
|
"comment4 */\n"
|
|
|
|
"# expansion begin 70,3 ~1\n"
|
|
|
|
"0\n"
|
|
|
|
"# expansion end\n"
|
|
|
|
"# 4 \"<stdin>\"\n"
|
|
|
|
);
|
|
|
|
|
|
|
|
QTest::newRow("case 11") << _(
|
|
|
|
"#include <foo.h> // comment\n"
|
|
|
|
) << _(
|
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
) << _(
|
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
" // comment\n"
|
|
|
|
);
|
2014-02-04 22:23:27 +02:00
|
|
|
|
|
|
|
QTest::newRow("joined") << _(
|
|
|
|
"// comment \\\n"
|
|
|
|
"\n"
|
|
|
|
"int foo = 4;"
|
|
|
|
) << _(
|
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"int foo = 4;"
|
|
|
|
) << _(
|
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"// comment \\\n"
|
|
|
|
"\n"
|
|
|
|
"int foo = 4;"
|
|
|
|
);
|
2014-02-05 08:37:33 +02:00
|
|
|
|
|
|
|
QTest::newRow("joined_unterminated") << _(
|
|
|
|
"// comment \\\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"int foo = 4;"
|
|
|
|
) << _(
|
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"# 12 \"<stdin>\"\n"
|
|
|
|
"int foo = 4;"
|
|
|
|
) << _(
|
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"// comment \\\n"
|
|
|
|
"\n"
|
|
|
|
"# 12 \"<stdin>\"\n"
|
|
|
|
"int foo = 4;"
|
|
|
|
);
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
}
|
|
|
|
|
2013-01-17 17:26:26 +01:00
|
|
|
void tst_Preprocessor::comments_before_args()
|
|
|
|
{
|
|
|
|
Client *client = 0; // no client.
|
|
|
|
Environment env;
|
|
|
|
|
|
|
|
Preprocessor preprocess(client, &env);
|
|
|
|
preprocess.setKeepComments(true);
|
|
|
|
QByteArray preprocessed = preprocess.run(QLatin1String("<stdin>"),
|
|
|
|
"\n#define foo(a,b) int a = b;"
|
|
|
|
"\nfoo/*C comment*/(a,1)\n"
|
|
|
|
"\nfoo/**Doxygen comment*/(b,2)\n"
|
|
|
|
"\nfoo//C++ comment\n(c,3)\n"
|
|
|
|
"\nfoo///Doxygen C++ comment\n(d,4)\n"
|
|
|
|
"\nfoo/*multiple*///comments\n/**as well*/(e,5)\n",
|
|
|
|
true, false);
|
|
|
|
|
|
|
|
preprocessed = preprocessed.simplified();
|
|
|
|
// DUMP_OUTPUT(preprocessed);
|
|
|
|
QCOMPARE(simplified(preprocessed),
|
|
|
|
QString("int a=1;int b=2;int c=3;int d=4;int e=5;"));
|
|
|
|
}
|
|
|
|
|
2012-08-20 23:11:34 +02:00
|
|
|
void tst_Preprocessor::multiline_strings()
|
|
|
|
{
|
|
|
|
compare_input_output();
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_Preprocessor::multiline_strings_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<QByteArray>("input");
|
|
|
|
QTest::addColumn<QByteArray>("output");
|
|
|
|
|
2014-01-13 22:57:32 +02:00
|
|
|
QTest::newRow("case 1") << _(
|
|
|
|
"const char *s = \"abc\\\n"
|
|
|
|
"xyz\";\n"
|
|
|
|
) << _(
|
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"const char *s = \"abc\\\n"
|
|
|
|
"xyz\";\n"
|
|
|
|
);
|
2012-08-20 23:11:34 +02:00
|
|
|
}
|
|
|
|
|
2012-08-29 13:21:22 +02:00
|
|
|
void tst_Preprocessor::skip_unknown_directives()
|
|
|
|
{
|
|
|
|
compare_input_output();
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_Preprocessor::skip_unknown_directives_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<QByteArray>("input");
|
|
|
|
QTest::addColumn<QByteArray>("output");
|
|
|
|
|
|
|
|
// We should skip "weird" things when preprocessing. Particularly useful when we preprocess
|
|
|
|
// a particular expression from a document which has already been processed.
|
|
|
|
|
2014-01-13 22:57:32 +02:00
|
|
|
QTest::newRow("case 1") << _(
|
|
|
|
"# foo\n"
|
|
|
|
"# 10 \"file.cpp\"\n"
|
|
|
|
"# ()\n"
|
|
|
|
"#\n"
|
|
|
|
) << _(
|
2013-05-30 15:03:54 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
);
|
2012-08-29 13:21:22 +02:00
|
|
|
}
|
|
|
|
|
2012-12-21 17:08:21 +01:00
|
|
|
void tst_Preprocessor::include_guard()
|
|
|
|
{
|
|
|
|
QFETCH(QString, includeGuard);
|
|
|
|
QFETCH(QString, input);
|
|
|
|
|
|
|
|
QByteArray output;
|
|
|
|
Environment env;
|
|
|
|
MockClient client(&env, &output);
|
|
|
|
Preprocessor preprocess(&client, &env);
|
|
|
|
preprocess.setKeepComments(true);
|
|
|
|
/*QByteArray prep =*/ preprocess.run(QLatin1String("<test-case>"), input);
|
|
|
|
QCOMPARE(QString::fromUtf8(client.includeGuard()), includeGuard);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_Preprocessor::include_guard_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<QString>("includeGuard");
|
|
|
|
QTest::addColumn<QString>("input");
|
|
|
|
|
|
|
|
QTest::newRow("basic-test") << "BASIC_TEST"
|
|
|
|
<< "#ifndef BASIC_TEST\n"
|
|
|
|
"#define BASIC_TEST\n"
|
|
|
|
"\n"
|
|
|
|
"#endif // BASIC_TEST\n";
|
|
|
|
QTest::newRow("comments-1") << "GUARD"
|
|
|
|
<< "/* some\n"
|
|
|
|
" * copyright\n"
|
|
|
|
" * header.\n"
|
|
|
|
" */\n"
|
|
|
|
"#ifndef GUARD\n"
|
|
|
|
"#define GUARD\n"
|
|
|
|
"\n"
|
|
|
|
"#endif // GUARD\n";
|
|
|
|
QTest::newRow("comments-2") << "GUARD"
|
|
|
|
<< "#ifndef GUARD\n"
|
|
|
|
"#define GUARD\n"
|
|
|
|
"\n"
|
|
|
|
"#endif // GUARD\n"
|
|
|
|
"/* some\n"
|
|
|
|
" * trailing\n"
|
|
|
|
" * comments.\n"
|
|
|
|
" */\n"
|
|
|
|
;
|
|
|
|
QTest::newRow("nested-ifdef") << "GUARD"
|
|
|
|
<< "#ifndef GUARD\n"
|
|
|
|
"#define GUARD\n"
|
|
|
|
"#ifndef NOT_GUARD\n"
|
|
|
|
"#define NOT_GUARD\n"
|
|
|
|
"#endif // NOT_GUARD\n"
|
|
|
|
"\n"
|
|
|
|
"#endif // GUARD\n"
|
|
|
|
;
|
|
|
|
QTest::newRow("leading-tokens") << ""
|
|
|
|
<< "int i;\n"
|
|
|
|
"#ifndef GUARD\n"
|
|
|
|
"#define GUARD\n"
|
|
|
|
"\n"
|
|
|
|
"#endif // GUARD\n"
|
|
|
|
;
|
|
|
|
QTest::newRow("trailing-tokens") << ""
|
|
|
|
<< "#ifndef GUARD\n"
|
|
|
|
"#define GUARD\n"
|
|
|
|
"\n"
|
|
|
|
"#endif // GUARD\n"
|
|
|
|
"int i;\n"
|
|
|
|
;
|
|
|
|
QTest::newRow("surprising-but-correct") << "GUARD"
|
|
|
|
<< "#ifndef GUARD\n"
|
|
|
|
"int i;\n"
|
|
|
|
"\n"
|
|
|
|
"#define GUARD\n"
|
|
|
|
"#endif // GUARD\n"
|
|
|
|
;
|
|
|
|
QTest::newRow("incomplete-1") << ""
|
|
|
|
<< "#ifndef GUARD\n"
|
|
|
|
;
|
|
|
|
QTest::newRow("incomplete-2") << "GUARD"
|
|
|
|
<< "#ifndef GUARD\n"
|
|
|
|
"#define GUARD\n"
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
2013-05-30 15:03:54 +02:00
|
|
|
void tst_Preprocessor::empty_trailing_lines()
|
|
|
|
{
|
|
|
|
compare_input_output();
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_Preprocessor::empty_trailing_lines_data()
|
|
|
|
{
|
|
|
|
// Test if the number of lines at the end of a file is correct. This is important to make the
|
|
|
|
// EOF token for the end up at the correct line.
|
|
|
|
|
|
|
|
QTest::addColumn<QByteArray>("input");
|
|
|
|
QTest::addColumn<QByteArray>("output");
|
|
|
|
|
2014-01-13 22:57:32 +02:00
|
|
|
const QByteArray original =
|
2013-05-30 15:03:54 +02:00
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
"\n";
|
|
|
|
|
|
|
|
QTest::newRow("9 empty lines")
|
|
|
|
<< original
|
|
|
|
<< _("# 1 \"<stdin>\"\n") + original;
|
2013-05-30 15:03:54 +02:00
|
|
|
|
2014-01-13 22:57:32 +02:00
|
|
|
QTest::newRow("11 empty lines") << _(
|
2013-05-30 15:03:54 +02:00
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
) << _(
|
2013-05-30 15:03:54 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"# 11 \"<stdin>\"\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
);
|
2013-05-30 15:03:54 +02:00
|
|
|
|
2014-01-13 22:57:32 +02:00
|
|
|
QTest::newRow("1 include") << _(
|
2013-05-30 15:03:54 +02:00
|
|
|
"#include <something>\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
) << _(
|
2013-05-30 15:03:54 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
);
|
2013-05-30 15:03:54 +02:00
|
|
|
|
2014-01-13 22:57:32 +02:00
|
|
|
QTest::newRow("1 empty line with 1 include") << _(
|
2013-05-30 15:03:54 +02:00
|
|
|
"#include <something>\n"
|
|
|
|
"\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
) << _(
|
2013-05-30 15:03:54 +02:00
|
|
|
"# 1 \"<stdin>\"\n"
|
|
|
|
"\n"
|
|
|
|
"\n"
|
2014-01-13 22:57:32 +02:00
|
|
|
);
|
2013-05-30 15:03:54 +02:00
|
|
|
}
|
|
|
|
|
2014-02-06 23:18:18 +02:00
|
|
|
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"));
|
2014-05-09 10:04:13 -04:00
|
|
|
QCOMPARE(macro->bytesOffset(), 8U);
|
2014-02-06 23:18:18 +02:00
|
|
|
QCOMPARE(macro->line(), 1U);
|
|
|
|
QVERIFY(!macro->isHidden());
|
|
|
|
macro = env.macroAt(1);
|
|
|
|
QCOMPARE(macro->name(), QByteArray("FOO2"));
|
2014-05-09 10:04:13 -04:00
|
|
|
QCOMPARE(macro->bytesOffset(), 20U);
|
2014-02-06 23:18:18 +02:00
|
|
|
QCOMPARE(macro->line(), 2U);
|
|
|
|
QVERIFY(!macro->isHidden());
|
|
|
|
macro = env.macroAt(2);
|
|
|
|
QCOMPARE(macro->name(), QByteArray("FOO"));
|
2014-05-09 10:04:13 -04:00
|
|
|
QCOMPARE(macro->bytesOffset(), 32U);
|
2014-02-06 23:18:18 +02:00
|
|
|
QCOMPARE(macro->line(), 3U);
|
|
|
|
QVERIFY(macro->isHidden());
|
|
|
|
macro = env.macroAt(3);
|
|
|
|
QCOMPARE(macro->name(), QByteArray("BAR"));
|
2014-05-09 10:04:13 -04:00
|
|
|
QCOMPARE(macro->bytesOffset(), 43U);
|
2014-02-06 23:18:18 +02:00
|
|
|
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());
|
|
|
|
}
|
|
|
|
|
2012-08-07 10:47:38 +02:00
|
|
|
void tst_Preprocessor::compare_input_output(bool keepComments)
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
{
|
|
|
|
QFETCH(QByteArray, input);
|
|
|
|
QFETCH(QByteArray, output);
|
|
|
|
|
|
|
|
Environment env;
|
|
|
|
Preprocessor preprocess(0, &env);
|
2012-08-07 10:47:38 +02:00
|
|
|
preprocess.setKeepComments(keepComments);
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
QByteArray prep = preprocess.run(QLatin1String("<stdin>"), input);
|
2013-05-30 15:03:54 +02:00
|
|
|
QCOMPARE(prep.constData(), output.constData());
|
C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
a more intuitive and natural expansion (like from a real compiler) is
performed directly corresponding to the macro invocation. Notice that
information about the generated tokens is not lost, because it's now
embedded in the expansion section header (in terms of lines and columns
as explained in the code). In addition the location on where the macro
expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
This was not detected in tests cases because some of them were
actually wrong: Within expansions the line information was being
considered as originally computed in the macro definition, while
the desired and expected for Creator's reporting mechanism (just
like regular compilers) is the line from the expanded version
of the tokens.
- Do not allow for eager expansion. This was previously being done
inside define directives. However, it's not allowed and might
lead to incorrect results, since the argument substitution should
only happen upon the macro invocation (and following nested ones).
At least GCC and clang are consistent with that. See test case
tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
that originates from a macro expansion. Notice, however, that
expanded tokens are not necessarily generated tokens (although
every generated token is a expanded token). Expanded tokens that
are not generated are those which are still considered by our
code model features, since they are visible on the editor. The
translation unit is smart enough to calculate line/column position
for such tokens based on the information from the expansion section
header.
- How expansions are tracked has also changed. Now, we simply add
two surrounding marker tokens to each "top-level" expansion
sequence. There is an enumeration that control expansion states.
Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
they now receive the line number of the action in question as
a paramater. Previously such line could be retrieved by the client
implementation by accessing the environment line. However, this
is not reliable because we try to avoid synchronization of the
output/environment lines in order to avoid unnecessary output,
while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
mentioned above) the preprocessor client is now "notified"
when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
|
|
|
}
|
|
|
|
|
2009-03-02 11:30:43 +01:00
|
|
|
QTEST_APPLESS_MAIN(tst_Preprocessor)
|
2012-04-19 15:19:38 +02:00
|
|
|
|
2009-03-02 11:30:43 +01:00
|
|
|
#include "tst_preprocessor.moc"
|