From e253f393600e3b79338f0d5943928fea7999af24 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Wed, 4 Mar 2009 11:47:30 +0100 Subject: [PATCH] Store the actual arguments of the macro expansions. --- src/libs/cplusplus/CppDocument.cpp | 29 ++++++++++- src/libs/cplusplus/CppDocument.h | 30 ++++++++--- src/libs/cplusplus/PreprocessorClient.h | 23 ++++++++- src/libs/cplusplus/pp-engine.cpp | 64 +++++++++++++++++++----- src/libs/cplusplus/pp-engine.h | 6 ++- src/plugins/cpptools/cppmodelmanager.cpp | 10 ++-- 6 files changed, 133 insertions(+), 29 deletions(-) diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp index 5be2a0b198e..012c243de1c 100644 --- a/src/libs/cplusplus/CppDocument.cpp +++ b/src/libs/cplusplus/CppDocument.cpp @@ -28,6 +28,7 @@ **************************************************************************/ #include "CppDocument.h" +#include "pp.h" #include #include @@ -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 &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); +} + diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h index 26a8b0f9b47..556e1293335 100644 --- a/src/libs/cplusplus/CppDocument.h +++ b/src/libs/cplusplus/CppDocument.h @@ -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 &range); Control *control() const; TranslationUnit *translationUnit() const; @@ -201,6 +203,7 @@ public: class MacroUse: public Block { Macro _macro; + QVector _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 arguments() const + { return _arguments; } + + void setArguments(const QVector &arguments) + { _arguments = arguments; } + + void addArgument(const Block &block) + { _arguments.append(block); } }; QList includes() const @@ -241,12 +256,15 @@ private: class CPLUSPLUS_EXPORT Snapshot: public QMap { -public: - Snapshot() - { } + typedef QMap _Base; - ~Snapshot() - { } +public: + Snapshot(); + ~Snapshot(); + + void insert(Document::Ptr doc); + + using _Base::insert; }; } // end of namespace CPlusPlus diff --git a/src/libs/cplusplus/PreprocessorClient.h b/src/libs/cplusplus/PreprocessorClient.h index 8a0fdcf9305..632cb3b9d5e 100644 --- a/src/libs/cplusplus/PreprocessorClient.h +++ b/src/libs/cplusplus/PreprocessorClient.h @@ -31,7 +31,7 @@ #define CPLUSPLUS_PP_CLIENT_H #include -#include +#include 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 &actuals + = QVector()) = 0; virtual void stopExpandingMacro(unsigned offset, const Macro ¯o) = 0; diff --git a/src/libs/cplusplus/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp index 5b6320d2f23..d3ffabe3416 100644 --- a/src/libs/cplusplus/pp-engine.cpp +++ b/src/libs/cplusplus/pp-engine.cpp @@ -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 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 *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 &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); diff --git a/src/libs/cplusplus/pp-engine.h b/src/libs/cplusplus/pp-engine.h index b2987413eb9..eb0ddea66d6 100644 --- a/src/libs/cplusplus/pp-engine.h +++ b/src/libs/cplusplus/pp-engine.h @@ -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 &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 *actuals); + MacroArgumentReference collectOneActualArgument(); void processNewline(); diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index 5847d509e16..3aa8136dff0 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -191,7 +191,8 @@ protected: virtual void macroAdded(const Macro ¯o); virtual void startExpandingMacro(unsigned offset, const Macro ¯o, - const QByteArray &originalText); + const QByteArray &originalText, + const QVector &actuals); virtual void stopExpandingMacro(unsigned offset, const Macro ¯o); virtual void startSkippingBlocks(unsigned offset); virtual void stopSkippingBlocks(unsigned offset); @@ -404,13 +405,14 @@ void CppPreprocessor::macroAdded(const Macro ¯o) void CppPreprocessor::startExpandingMacro(unsigned offset, const Macro ¯o, - const QByteArray &originalText) + const QByteArray &originalText, + const QVector &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);