Commit 4b338817 authored by Wolfgang Beck's avatar Wolfgang Beck

Merge ichecker branch changes into the mainline. New project can be found under src/tools/ICheck

parent 29b7594b
......@@ -871,27 +871,33 @@ void Preprocessor::preprocess(const QString &fileName, const QByteArray &source,
expandBuiltinMacro(identifierToken, spell);
else {
if (Macro *m = env->resolve(spell)) {
if (! m->isFunctionLike()) {
if (0 == (m = processObjectLikeMacro(identifierToken, spell, m)))
continue;
#ifdef ICHECK_BUILD
if(spell != "Q_PROPERTY" && spell != "Q_INVOKABLE" && spell != "Q_ENUMS"
&& spell != "Q_FLAGS" && spell != "Q_DECLARE_FLAGS"){
#endif
if (Macro *m = env->resolve(spell)) {
if (! m->isFunctionLike()) {
if (0 == (m = processObjectLikeMacro(identifierToken, spell, m)))
continue;
// the macro expansion generated something that looks like
// a function-like macro.
}
// the macro expansion generated something that looks like
// a function-like macro.
}
// `m' is function-like macro.
if (_dot->is(T_LPAREN)) {
QVector<MacroArgumentReference> actuals;
collectActualArguments(&actuals);
// `m' is function-like macro.
if (_dot->is(T_LPAREN)) {
QVector<MacroArgumentReference> actuals;
collectActualArguments(&actuals);
if (_dot->is(T_RPAREN)) {
expandFunctionLikeMacro(identifierToken, m, actuals);
continue;
if (_dot->is(T_RPAREN)) {
expandFunctionLikeMacro(identifierToken, m, actuals);
continue;
}
}
}
#ifdef ICHECK_BUILD
}
#endif
// it's not a function or object-like macro.
out(spell);
}
......
......@@ -161,73 +161,7 @@ static const char pp_configuration[] =
"#define __declspec(a)\n"
"#define STDMETHOD(method) virtual HRESULT STDMETHODCALLTYPE method\n";
namespace CppTools {
namespace Internal {
class CppPreprocessor: public CPlusPlus::Client
{
public:
CppPreprocessor(QPointer<CppModelManager> modelManager);
virtual ~CppPreprocessor();
void setRevision(unsigned revision);
void setWorkingCopy(const CppModelManagerInterface::WorkingCopy &workingCopy);
void setIncludePaths(const QStringList &includePaths);
void setFrameworkPaths(const QStringList &frameworkPaths);
void setProjectFiles(const QStringList &files);
void setTodo(const QStringList &files);
void run(const QString &fileName);
void resetEnvironment();
const QSet<QString> &todo() const
{ return m_todo; }
public: // attributes
Snapshot snapshot;
protected:
CPlusPlus::Document::Ptr switchDocument(CPlusPlus::Document::Ptr doc);
bool includeFile(const QString &absoluteFilePath, QString *result, unsigned *revision);
QString tryIncludeFile(QString &fileName, IncludeType type, unsigned *revision);
void mergeEnvironment(CPlusPlus::Document::Ptr doc);
virtual void macroAdded(const Macro &macro);
virtual void passedMacroDefinitionCheck(unsigned offset, const Macro &macro);
virtual void failedMacroDefinitionCheck(unsigned offset, const QByteArray &name);
virtual void startExpandingMacro(unsigned offset,
const Macro &macro,
const QByteArray &originalText,
bool inCondition,
const QVector<MacroArgumentReference> &actuals);
virtual void stopExpandingMacro(unsigned offset, const Macro &macro);
virtual void startSkippingBlocks(unsigned offset);
virtual void stopSkippingBlocks(unsigned offset);
virtual void sourceNeeded(QString &fileName, IncludeType type,
unsigned line);
private:
QPointer<CppModelManager> m_modelManager;
Environment env;
Preprocessor preprocess;
QStringList m_includePaths;
QStringList m_systemIncludePaths;
CppModelManagerInterface::WorkingCopy m_workingCopy;
QStringList m_projectFiles;
QStringList m_frameworkPaths;
QSet<QString> m_included;
Document::Ptr m_currentDoc;
QSet<QString> m_todo;
QSet<QString> m_processed;
unsigned m_revision;
};
} // namespace Internal
} // namespace CppTools
#ifndef ICHECK_BUILD
CppPreprocessor::CppPreprocessor(QPointer<CppModelManager> modelManager)
: snapshot(modelManager->snapshot()),
m_modelManager(modelManager),
......@@ -235,6 +169,15 @@ CppPreprocessor::CppPreprocessor(QPointer<CppModelManager> modelManager)
m_revision(0)
{ }
#else
CppPreprocessor::CppPreprocessor(QPointer<CPlusPlus::ParseManager> modelManager)
: preprocess(this, &env),
m_revision(0)
{
}
#endif
CppPreprocessor::~CppPreprocessor()
{ }
......@@ -258,7 +201,7 @@ void CppPreprocessor::setTodo(const QStringList &files)
namespace {
#ifndef ICHECK_BUILD
class Process: public std::unary_function<Document::Ptr, void>
{
QPointer<CppModelManager> _modelManager;
......@@ -313,7 +256,7 @@ public:
_modelManager->emitDocumentUpdated(doc); // ### TODO: compress
}
};
#endif
} // end of anonymous namespace
void CppPreprocessor::run(const QString &fileName)
......@@ -580,11 +523,19 @@ void CppPreprocessor::sourceNeeded(QString &fileName, IncludeType type, unsigned
snapshot.insert(doc);
m_todo.remove(fileName);
#ifndef ICHECK_BUILD
Process process(m_modelManager, snapshot, m_workingCopy);
process(doc);
(void) switchDocument(previousDoc);
#else
(void) switchDocument(previousDoc);
Document::CheckMode mode = Document::FastCheck;
mode = Document::FullCheck;
doc->parse();
doc->check(mode);
#endif
}
Document::Ptr CppPreprocessor::switchDocument(Document::Ptr doc)
......@@ -594,6 +545,7 @@ Document::Ptr CppPreprocessor::switchDocument(Document::Ptr doc)
return previousDoc;
}
#ifndef ICHECK_BUILD
void CppTools::CppModelManagerInterface::updateModifiedSourceFiles()
{
const Snapshot snapshot = this->snapshot();
......@@ -1397,5 +1349,5 @@ void CppModelManager::GC()
m_snapshot = newSnapshot;
protectSnapshot.unlock();
}
#endif
......@@ -33,9 +33,13 @@
#include <cpptools/cppmodelmanagerinterface.h>
#include <projectexplorer/project.h>
#include <cplusplus/CppDocument.h>
#include <cplusplus/PreprocessorClient.h>
#include <texteditor/basetexteditor.h>
#include <cplusplus/PreprocessorEnvironment.h>
#include <cplusplus/pp-engine.h>
#ifdef ICHECK_BUILD
# include "ParseManager.h"
#endif
#include <QtCore/QHash>
#include <QtCore/QFutureInterface>
#include <QtCore/QFutureSynchronizer>
......@@ -57,13 +61,19 @@ namespace ProjectExplorer {
class ProjectExplorerPlugin;
}
namespace CPlusPlus {
class ParseManager;
}
namespace CppTools {
namespace Internal {
class CppEditorSupport;
class CppPreprocessor;
class CppFindReferences;
#ifndef ICHECK_BUILD
class CppModelManager : public CppModelManagerInterface
{
Q_OBJECT
......@@ -221,6 +231,75 @@ private:
CppFindReferences *m_findReferences;
bool m_indexerEnabled;
};
#endif
using namespace CPlusPlus;
class CppPreprocessor: public CPlusPlus::Client
{
public:
#ifndef ICHECK_BUILD
CppPreprocessor(QPointer<CppModelManager> modelManager);
#else
CppPreprocessor(QPointer<CPlusPlus::ParseManager> modelManager);
#endif
virtual ~CppPreprocessor();
void setRevision(unsigned revision);
void setWorkingCopy(const CppModelManagerInterface::WorkingCopy &workingCopy);
void setIncludePaths(const QStringList &includePaths);
void setFrameworkPaths(const QStringList &frameworkPaths);
void setProjectFiles(const QStringList &files);
void setTodo(const QStringList &files);
void run(const QString &fileName);
void resetEnvironment();
const QSet<QString> &todo() const
{ return m_todo; }
public: // attributes
Snapshot snapshot;
protected:
CPlusPlus::Document::Ptr switchDocument(CPlusPlus::Document::Ptr doc);
bool includeFile(const QString &absoluteFilePath, QString *result, unsigned *revision);
QString tryIncludeFile(QString &fileName, IncludeType type, unsigned *revision);
void mergeEnvironment(CPlusPlus::Document::Ptr doc);
virtual void macroAdded(const Macro &macro);
virtual void passedMacroDefinitionCheck(unsigned offset, const Macro &macro);
virtual void failedMacroDefinitionCheck(unsigned offset, const QByteArray &name);
virtual void startExpandingMacro(unsigned offset,
const Macro &macro,
const QByteArray &originalText,
bool inCondition,
const QVector<MacroArgumentReference> &actuals);
virtual void stopExpandingMacro(unsigned offset, const Macro &macro);
virtual void startSkippingBlocks(unsigned offset);
virtual void stopSkippingBlocks(unsigned offset);
virtual void sourceNeeded(QString &fileName, IncludeType type,
unsigned line);
private:
#ifndef ICHECK_BUILD
QPointer<CppModelManager> m_modelManager;
#endif
Environment env;
Preprocessor preprocess;
QStringList m_includePaths;
QStringList m_systemIncludePaths;
CppModelManagerInterface::WorkingCopy m_workingCopy;
QStringList m_projectFiles;
QStringList m_frameworkPaths;
QSet<QString> m_included;
Document::Ptr m_currentDoc;
QSet<QString> m_todo;
QSet<QString> m_processed;
unsigned m_revision;
};
} // namespace Internal
} // namespace CppTools
......
......@@ -144,6 +144,47 @@ unsigned AccessDeclarationAST::lastToken() const
return access_specifier_token + 1;
}
#ifdef ICHECK_BUILD
unsigned QPropertyDeclarationAST::firstToken() const
{
return property_specifier_token;
}
unsigned QPropertyDeclarationAST::lastToken() const
{
return rparen_token;
}
unsigned QEnumDeclarationAST::firstToken() const
{
return enum_specifier_token;
}
unsigned QEnumDeclarationAST::lastToken() const
{
return rparen_token;
}
unsigned QFlagsDeclarationAST::firstToken() const
{
return this->flags_specifier_token;
}
unsigned QFlagsDeclarationAST::lastToken() const
{
return rparen_token;
}
unsigned QDeclareFlagsDeclarationAST::firstToken() const
{
return declareflags_specifier_token;
}
unsigned QDeclareFlagsDeclarationAST::lastToken() const
{
return rparen_token;
}
#endif
unsigned ArrayAccessAST::firstToken() const
{
......@@ -1600,7 +1641,9 @@ unsigned ThrowExpressionAST::lastToken() const
unsigned TranslationUnitAST::firstToken() const
{
return declaration_list->firstToken();
if(declaration_list)
return declaration_list->firstToken();
return 0;
}
unsigned TranslationUnitAST::lastToken() const
......
......@@ -146,6 +146,12 @@ public:
virtual AccessDeclarationAST *asAccessDeclaration() { return 0; }
virtual ArrayAccessAST *asArrayAccess() { return 0; }
virtual ArrayDeclaratorAST *asArrayDeclarator() { return 0; }
#ifdef ICHECK_BUILD
virtual QPropertyDeclarationAST *asQPropertyDeclarationAST() { return 0; }
virtual QEnumDeclarationAST *asQEnumDeclarationAST() { return 0; }
virtual QFlagsDeclarationAST *asQFlagsDeclarationAST() { return 0; }
virtual QDeclareFlagsDeclarationAST *asQDeclareFlagsDeclarationAST() { return 0; }
#endif
virtual ArrayInitializerAST *asArrayInitializer() { return 0; }
virtual AsmDefinitionAST *asAsmDefinition() { return 0; }
virtual AttributeAST *asAttribute() { return 0; }
......@@ -298,6 +304,9 @@ class CPLUSPLUS_EXPORT DeclarationAST: public AST
{
public:
virtual DeclarationAST *asDeclaration() { return this; }
#ifdef ICHECK_BUILD
unsigned invoke_token;
#endif
};
class CPLUSPLUS_EXPORT NameAST: public ExpressionAST
......@@ -502,6 +511,109 @@ protected:
virtual bool match0(AST *, ASTMatcher *);
};
#ifdef ICHECK_BUILD
class CPLUSPLUS_EXPORT QPropertyDeclarationAST: public DeclarationAST
{
/*
Q_PROPERTY(type name
READ getFunction
[WRITE setFunction]
[RESET resetFunction]
[NOTIFY notifySignal]
[DESIGNABLE bool]
[SCRIPTABLE bool]
[STORED bool]
[USER bool]
[CONSTANT]
[FINAL])*/
public:
unsigned property_specifier_token;
unsigned lparen_token;
unsigned type_token;
unsigned type_name_token;
unsigned read_token;
unsigned read_function_token;
unsigned write_token;
unsigned write_function_token;
unsigned reset_token;
unsigned reset_function_token;
unsigned notify_token;
unsigned notify_function_token;
unsigned rparen_token;
public:
virtual QPropertyDeclarationAST *asQPropertyDeclarationAST() { return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
protected:
virtual void accept0(ASTVisitor *visitor);
virtual bool match0(AST *, ASTMatcher *);
};
class CPLUSPLUS_EXPORT QEnumDeclarationAST: public DeclarationAST
{
/*Q_ENUMS(enum1, enum2)*/
public:
unsigned enum_specifier_token;
unsigned lparen_token;
unsigned rparen_token;
EnumeratorListAST *enumerator_list;
public:
virtual QEnumDeclarationAST *asQEnumDeclarationAST() { return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
protected:
virtual void accept0(ASTVisitor *visitor);
virtual bool match0(AST *, ASTMatcher *);
};
class CPLUSPLUS_EXPORT QFlagsDeclarationAST: public DeclarationAST
{
/*Q_FLAGS(enum1 enum2 flags1 ...)*/
public:
unsigned flags_specifier_token;
unsigned lparen_token;
unsigned rparen_token;
EnumeratorListAST *enumerator_list;
public:
virtual QFlagsDeclarationAST *asQFlagsDeclarationAST() { return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
protected:
virtual void accept0(ASTVisitor *visitor);
virtual bool match0(AST *, ASTMatcher *);
};
class CPLUSPLUS_EXPORT QDeclareFlagsDeclarationAST: public DeclarationAST
{
/*Q_DECLARE_FLAGS(flag enum)*/
public:
unsigned declareflags_specifier_token;
unsigned lparen_token;
unsigned flag_token;
unsigned enum_token;
unsigned rparen_token;
public:
virtual QDeclareFlagsDeclarationAST *asQDeclareFlagsDeclarationAST() { return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
protected:
virtual void accept0(ASTVisitor *visitor);
virtual bool match0(AST *, ASTMatcher *);
};
#endif
class CPLUSPLUS_EXPORT AsmDefinitionAST: public DeclarationAST
{
public:
......
......@@ -96,6 +96,40 @@ bool AccessDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
return false;
}
#ifdef ICHECK_BUILD
bool QPropertyDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (QPropertyDeclarationAST *_other = pattern->asQPropertyDeclarationAST())
return matcher->match(this, _other);
return false;
}
bool QEnumDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (QEnumDeclarationAST *_other = pattern->asQEnumDeclarationAST())
return matcher->match(this, _other);
return false;
}
bool QFlagsDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (QFlagsDeclarationAST *_other = pattern->asQFlagsDeclarationAST())
return matcher->match(this, _other);
return false;
}
bool QDeclareFlagsDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (QDeclareFlagsDeclarationAST *_other = pattern->asQDeclareFlagsDeclarationAST())
return matcher->match(this, _other);
return false;
}
#endif
bool AsmDefinitionAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (AsmDefinitionAST *_other = pattern->asAsmDefinition())
......
......@@ -195,8 +195,74 @@ bool ASTMatcher::match(AccessDeclarationAST *node, AccessDeclarationAST *pattern
pattern->colon_token = node->colon_token;
#ifdef ICHECK_BUILD
pattern->invoke_token = node->invoke_token;
#endif
return true;
}
#ifdef ICHECK_BUILD
bool ASTMatcher::match(QPropertyDeclarationAST *node, QPropertyDeclarationAST *pattern)
{
(void) node;
(void) pattern;
pattern->property_specifier_token = node->property_specifier_token;
pattern->type_name_token = node->type_name_token;
pattern->read_function_token = node->read_function_token;
pattern->write_function_token = node->write_function_token;
pattern->notify_function_token = node->notify_function_token;
return true;
}
bool ASTMatcher::match(QEnumDeclarationAST *node, QEnumDeclarationAST *pattern)
{
(void) node;
(void) pattern;
pattern->enum_specifier_token = node->enum_specifier_token;
if (! pattern->enumerator_list)
pattern->enumerator_list = node->enumerator_list;
else if (! AST::match(node->enumerator_list, pattern->enumerator_list, this))
return false;
return true;
}
bool ASTMatcher::match(QFlagsDeclarationAST *node, QFlagsDeclarationAST *pattern)
{
(void) node;
(void) pattern;
pattern->flags_specifier_token = node->flags_specifier_token;
if (! pattern->enumerator_list)
pattern->enumerator_list = node->enumerator_list;
else if (! AST::match(node->enumerator_list, pattern->enumerator_list, this))
return false;
return true;
}
bool ASTMatcher::match(QDeclareFlagsDeclarationAST *node, QDeclareFlagsDeclarationAST *pattern)
{
(void) node;
(void) pattern;
pattern->declareflags_specifier_token = node->declareflags_specifier_token;
pattern->flag_token = node->flag_token;
pattern->enum_token = node->enum_token;
return true;
}
#endif
bool ASTMatcher::match(AsmDefinitionAST *node, AsmDefinitionAST *pattern)
{
......
......@@ -40,6 +40,12 @@ public:
virtual ~ASTMatcher();
virtual bool match(AccessDeclarationAST *node, AccessDeclarationAST *pattern);
#ifdef ICHECK_BUILD
virtual bool match(QPropertyDeclarationAST *node, QPropertyDeclarationAST *pattern);
virtual bool match(QEnumDeclarationAST *node, QEnumDeclarationAST *pattern);
virtual bool match(QFlagsDeclarationAST *node, QFlagsDeclarationAST *pattern);
virtual bool match(QDeclareFlagsDeclarationAST *node, QDeclareFlagsDeclarationAST *pattern);
#endif
virtual bool match(ArrayAccessAST *node, ArrayAccessAST *pattern);
virtual bool match(ArrayDeclaratorAST *node, ArrayDeclaratorAST *pattern);
virtual bool match(ArrayInitializerAST *node, ArrayInitializerAST *pattern);
......
......@@ -99,6 +99,36 @@ void AccessDeclarationAST::accept0(ASTVisitor *visitor)
visitor->endVisit(this);
}