forked from qt-creator/qt-creator
Store the actual arguments of the macro expansions.
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
**************************************************************************/
|
||||
|
||||
#include "CppDocument.h"
|
||||
#include "pp.h"
|
||||
|
||||
#include <Control.h>
|
||||
#include <TranslationUnit.h>
|
||||
@@ -145,9 +146,18 @@ void Document::appendMacro(const Macro ¯o)
|
||||
_definedMacros.append(macro);
|
||||
}
|
||||
|
||||
void Document::addMacroUse(const Macro ¯o, unsigned offset, unsigned length)
|
||||
void Document::addMacroUse(const Macro ¯o, unsigned offset, unsigned length,
|
||||
const QVector<MacroArgumentReference> &actuals)
|
||||
{
|
||||
_macroUses.append(MacroUse(macro, offset, offset + length));
|
||||
MacroUse use(macro, offset, offset + length);
|
||||
|
||||
foreach (const MacroArgumentReference &actual, actuals) {
|
||||
const Block arg(actual.position(), actual.position() + actual.length());
|
||||
|
||||
use.addArgument(arg);
|
||||
}
|
||||
|
||||
_macroUses.append(use);
|
||||
}
|
||||
|
||||
TranslationUnit *Document::translationUnit() const
|
||||
@@ -316,3 +326,18 @@ void Document::releaseTranslationUnit()
|
||||
{
|
||||
_translationUnit->release();
|
||||
}
|
||||
|
||||
Snapshot::Snapshot()
|
||||
{
|
||||
}
|
||||
|
||||
Snapshot::~Snapshot()
|
||||
{
|
||||
}
|
||||
|
||||
void Snapshot::insert(Document::Ptr doc)
|
||||
{
|
||||
if (doc)
|
||||
insert(doc->fileName(), doc);
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
namespace CPlusPlus {
|
||||
|
||||
class Macro;
|
||||
class MacroArgumentReference;
|
||||
|
||||
class CPLUSPLUS_EXPORT Document
|
||||
{
|
||||
@@ -63,7 +64,8 @@ public:
|
||||
void addIncludeFile(const QString &fileName, unsigned line);
|
||||
|
||||
void appendMacro(const Macro ¯o);
|
||||
void addMacroUse(const Macro ¯o, unsigned offset, unsigned length);
|
||||
void addMacroUse(const Macro ¯o, unsigned offset, unsigned length,
|
||||
const QVector<MacroArgumentReference> &range);
|
||||
|
||||
Control *control() const;
|
||||
TranslationUnit *translationUnit() const;
|
||||
@@ -201,6 +203,7 @@ public:
|
||||
|
||||
class MacroUse: public Block {
|
||||
Macro _macro;
|
||||
QVector<Block> _arguments;
|
||||
|
||||
public:
|
||||
inline MacroUse(const Macro ¯o,
|
||||
@@ -212,6 +215,18 @@ public:
|
||||
|
||||
const Macro ¯o() const
|
||||
{ return _macro; }
|
||||
|
||||
bool isFunctionLike() const
|
||||
{ return _macro.isFunctionLike(); }
|
||||
|
||||
QVector<Block> arguments() const
|
||||
{ return _arguments; }
|
||||
|
||||
void setArguments(const QVector<Block> &arguments)
|
||||
{ _arguments = arguments; }
|
||||
|
||||
void addArgument(const Block &block)
|
||||
{ _arguments.append(block); }
|
||||
};
|
||||
|
||||
QList<Include> includes() const
|
||||
@@ -241,12 +256,15 @@ private:
|
||||
|
||||
class CPLUSPLUS_EXPORT Snapshot: public QMap<QString, Document::Ptr>
|
||||
{
|
||||
public:
|
||||
Snapshot()
|
||||
{ }
|
||||
typedef QMap<QString, Document::Ptr> _Base;
|
||||
|
||||
~Snapshot()
|
||||
{ }
|
||||
public:
|
||||
Snapshot();
|
||||
~Snapshot();
|
||||
|
||||
void insert(Document::Ptr doc);
|
||||
|
||||
using _Base::insert;
|
||||
};
|
||||
|
||||
} // end of namespace CPlusPlus
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#define CPLUSPLUS_PP_CLIENT_H
|
||||
|
||||
#include <CPlusPlusForwardDeclarations.h>
|
||||
#include <QtGlobal>
|
||||
#include <QVector>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QByteArray;
|
||||
@@ -42,6 +42,23 @@ namespace CPlusPlus {
|
||||
|
||||
class Macro;
|
||||
|
||||
class CPLUSPLUS_EXPORT MacroArgumentReference
|
||||
{
|
||||
unsigned _position;
|
||||
unsigned _length;
|
||||
|
||||
public:
|
||||
MacroArgumentReference(unsigned position = 0, unsigned length = 0)
|
||||
: _position(position), _length(length)
|
||||
{ }
|
||||
|
||||
unsigned position() const
|
||||
{ return _position; }
|
||||
|
||||
unsigned length() const
|
||||
{ return _length; }
|
||||
};
|
||||
|
||||
class CPLUSPLUS_EXPORT Client
|
||||
{
|
||||
Client(const Client &other);
|
||||
@@ -63,7 +80,9 @@ public:
|
||||
|
||||
virtual void startExpandingMacro(unsigned offset,
|
||||
const Macro ¯o,
|
||||
const QByteArray &originalTextt) = 0;
|
||||
const QByteArray &originalText,
|
||||
const QVector<MacroArgumentReference> &actuals
|
||||
= QVector<MacroArgumentReference>()) = 0;
|
||||
|
||||
virtual void stopExpandingMacro(unsigned offset,
|
||||
const Macro ¯o) = 0;
|
||||
|
||||
@@ -741,10 +741,11 @@ void Preprocessor::preprocess(const QByteArray &fileName, const QByteArray &sour
|
||||
|
||||
// `m' is function-like macro.
|
||||
if (_dot->is(T_LPAREN)) {
|
||||
skipActualArguments();
|
||||
QVector<MacroArgumentReference> actuals;
|
||||
collectActualArguments(&actuals);
|
||||
|
||||
if (_dot->is(T_RPAREN)) {
|
||||
expandFunctionLikeMacro(identifierToken, m);
|
||||
expandFunctionLikeMacro(identifierToken, m, actuals);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -764,21 +765,56 @@ void Preprocessor::preprocess(const QByteArray &fileName, const QByteArray &sour
|
||||
_result = previousResult;
|
||||
}
|
||||
|
||||
void Preprocessor::skipActualArguments()
|
||||
void Preprocessor::collectActualArguments(QVector<MacroArgumentReference> *actuals)
|
||||
{
|
||||
int count = 0;
|
||||
if (_dot->isNot(T_LPAREN))
|
||||
return;
|
||||
|
||||
++_dot;
|
||||
|
||||
if (_dot->is(T_RPAREN))
|
||||
return;
|
||||
|
||||
actuals->append(collectOneActualArgument());
|
||||
|
||||
while (_dot->is(T_COMMA)) {
|
||||
++_dot;
|
||||
|
||||
actuals->append(collectOneActualArgument());
|
||||
}
|
||||
}
|
||||
|
||||
MacroArgumentReference Preprocessor::collectOneActualArgument()
|
||||
{
|
||||
const unsigned position = _dot->begin();
|
||||
|
||||
while (_dot->isNot(T_EOF_SYMBOL)) {
|
||||
if (_dot->is(T_LPAREN))
|
||||
++count;
|
||||
if (_dot->is(T_COMMA) || _dot->is(T_RPAREN))
|
||||
break;
|
||||
|
||||
else if (_dot->is(T_RPAREN)) {
|
||||
if (! --count)
|
||||
break;
|
||||
if (_dot->isNot(T_LPAREN))
|
||||
++_dot;
|
||||
|
||||
else {
|
||||
int count = 0;
|
||||
|
||||
for (; _dot->isNot(T_EOF_SYMBOL); ++_dot) {
|
||||
if (_dot->is(T_LPAREN))
|
||||
++count;
|
||||
|
||||
else if (_dot->is(T_RPAREN)) {
|
||||
if (! --count) {
|
||||
++_dot;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++_dot;
|
||||
}
|
||||
|
||||
const unsigned end = _dot->begin();
|
||||
|
||||
return MacroArgumentReference(position, end - position);
|
||||
}
|
||||
|
||||
Macro *Preprocessor::processObjectLikeMacro(TokenIterator identifierToken,
|
||||
@@ -846,7 +882,9 @@ void Preprocessor::expandObjectLikeMacro(TokenIterator identifierToken,
|
||||
client->stopExpandingMacro(_dot->offset, *m);
|
||||
}
|
||||
|
||||
void Preprocessor::expandFunctionLikeMacro(TokenIterator identifierToken, Macro *m)
|
||||
void Preprocessor::expandFunctionLikeMacro(TokenIterator identifierToken,
|
||||
Macro *m,
|
||||
const QVector<MacroArgumentReference> &actuals)
|
||||
{
|
||||
const char *beginOfText = startOfToken(*identifierToken);
|
||||
const char *endOfText = endOfToken(*_dot);
|
||||
@@ -858,7 +896,7 @@ void Preprocessor::expandFunctionLikeMacro(TokenIterator identifierToken, Macro
|
||||
endOfText - beginOfText);
|
||||
|
||||
client->startExpandingMacro(identifierToken->offset,
|
||||
*m, text);
|
||||
*m, text, actuals);
|
||||
}
|
||||
|
||||
expand(beginOfText, endOfText, _result);
|
||||
|
||||
@@ -109,7 +109,8 @@ private:
|
||||
void expandObjectLikeMacro(TokenIterator identifierToken,
|
||||
const QByteArray &spell,
|
||||
Macro *m, QByteArray *result);
|
||||
void expandFunctionLikeMacro(TokenIterator identifierToken, Macro *m);
|
||||
void expandFunctionLikeMacro(TokenIterator identifierToken, Macro *m,
|
||||
const QVector<MacroArgumentReference> &actuals);
|
||||
|
||||
void resetIfLevel();
|
||||
bool testIfLevel();
|
||||
@@ -129,7 +130,8 @@ private:
|
||||
QByteArray tokenSpell(const CPlusPlus::Token &token) const;
|
||||
QByteArray tokenText(const CPlusPlus::Token &token) const; // does a deep copy
|
||||
|
||||
void skipActualArguments();
|
||||
void collectActualArguments(QVector<MacroArgumentReference> *actuals);
|
||||
MacroArgumentReference collectOneActualArgument();
|
||||
|
||||
void processNewline();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user