Commit e253f393 authored by Roberto Raggi's avatar Roberto Raggi
Browse files

Store the actual arguments of the macro expansions.

parent 08d0b03e
......@@ -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 &macro)
_definedMacros.append(macro);
}
void Document::addMacroUse(const Macro &macro, unsigned offset, unsigned length)
void Document::addMacroUse(const Macro &macro, 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 &macro);
void addMacroUse(const Macro &macro, unsigned offset, unsigned length);
void addMacroUse(const Macro &macro, 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 &macro,
......@@ -212,6 +215,18 @@ public:
const Macro &macro() 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>
{
typedef QMap<QString, Document::Ptr> _Base;
public:
Snapshot()
{ }
Snapshot();
~Snapshot();
void insert(Document::Ptr doc);
~Snapshot()
{ }
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 &macro,
const QByteArray &originalTextt) = 0;
const QByteArray &originalText,
const QVector<MacroArgumentReference> &actuals
= QVector<MacroArgumentReference>()) = 0;
virtual void stopExpandingMacro(unsigned offset,
const Macro &macro) = 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,23 +765,58 @@ 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;
while (_dot->isNot(T_EOF_SYMBOL)) {
if (_dot->is(T_LPAREN))
++count;
++_dot;
else if (_dot->is(T_RPAREN)) {
if (! --count)
break;
}
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_COMMA) || _dot->is(T_RPAREN))
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;
}
}
}
}
}
const unsigned end = _dot->begin();
return MacroArgumentReference(position, end - position);
}
Macro *Preprocessor::processObjectLikeMacro(TokenIterator identifierToken,
const QByteArray &spell,
Macro *m)
......@@ -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();
......
......@@ -191,7 +191,8 @@ protected:
virtual void macroAdded(const Macro &macro);
virtual void startExpandingMacro(unsigned offset,
const Macro &macro,
const QByteArray &originalText);
const QByteArray &originalText,
const QVector<MacroArgumentReference> &actuals);
virtual void stopExpandingMacro(unsigned offset, const Macro &macro);
virtual void startSkippingBlocks(unsigned offset);
virtual void stopSkippingBlocks(unsigned offset);
......@@ -404,13 +405,14 @@ void CppPreprocessor::macroAdded(const Macro &macro)
void CppPreprocessor::startExpandingMacro(unsigned offset,
const Macro &macro,
const QByteArray &originalText)
const QByteArray &originalText,
const QVector<MacroArgumentReference> &actuals)
{
if (! m_currentDoc)
return;
//qDebug() << "start expanding:" << macro.name << "text:" << originalText;
m_currentDoc->addMacroUse(macro, offset, originalText.length());
m_currentDoc->addMacroUse(macro, offset, originalText.length(), actuals);
}
void CppPreprocessor::stopExpandingMacro(unsigned, const Macro &)
......@@ -544,7 +546,7 @@ CppModelManager::CppModelManager(QObject *parent)
m_core = Core::ICore::instance(); // FIXME
m_dirty = true;
ProjectExplorer::ProjectExplorerPlugin *pe =
ProjectExplorer::ProjectExplorerPlugin *pe =
ProjectExplorer::ProjectExplorerPlugin::instance();
QTC_ASSERT(pe, return);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment