diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp index 5be2a0b198e6498026f147aa85b15ecd4f9c3890..012c243de1c05fd5d0b9020fe4246feac3b671f5 100644 --- a/src/libs/cplusplus/CppDocument.cpp +++ b/src/libs/cplusplus/CppDocument.cpp @@ -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); +} + diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h index 26a8b0f9b474a14fbe92510c5cf222c6602d83ca..556e1293335adaca284918754096f456da252090 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<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> { + typedef QMap<QString, Document::Ptr> _Base; + public: - Snapshot() - { } + Snapshot(); + ~Snapshot(); + + void insert(Document::Ptr doc); - ~Snapshot() - { } + using _Base::insert; }; } // end of namespace CPlusPlus diff --git a/src/libs/cplusplus/PreprocessorClient.h b/src/libs/cplusplus/PreprocessorClient.h index 8a0fdcf9305f2f966b5bcc508217ba3446dd82e9..632cb3b9d5ec9a89baad943b4b2075b3c44fed0d 100644 --- a/src/libs/cplusplus/PreprocessorClient.h +++ b/src/libs/cplusplus/PreprocessorClient.h @@ -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; diff --git a/src/libs/cplusplus/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp index 5b6320d2f237e38055d923a10aab0049329b11f8..d3ffabe34161d9f3bec9af41b10d82bf87666f22 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<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); diff --git a/src/libs/cplusplus/pp-engine.h b/src/libs/cplusplus/pp-engine.h index b2987413eb9006c89d5e4fb8059716ba81f72f1c..eb0ddea66d6e92164a7270502ec83230d1c5eb02 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<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(); diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index 5847d509e166420116d8df2812269cf7e25ca4de..3aa8136dff03acfaf9f7c3df391d7ca0fcaadad4 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<MacroArgumentReference> &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<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);