forked from qt-creator/qt-creator
Merge ichecker branch changes into the mainline. New project can be found under src/tools/ICheck
This commit is contained in:
@@ -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 ¯o);
|
||||
virtual void passedMacroDefinitionCheck(unsigned offset, const Macro ¯o);
|
||||
virtual void failedMacroDefinitionCheck(unsigned offset, const QByteArray &name);
|
||||
virtual void startExpandingMacro(unsigned offset,
|
||||
const Macro ¯o,
|
||||
const QByteArray &originalText,
|
||||
bool inCondition,
|
||||
const QVector<MacroArgumentReference> &actuals);
|
||||
virtual void stopExpandingMacro(unsigned offset, const Macro ¯o);
|
||||
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 ¯o);
|
||||
virtual void passedMacroDefinitionCheck(unsigned offset, const Macro ¯o);
|
||||
virtual void failedMacroDefinitionCheck(unsigned offset, const QByteArray &name);
|
||||
virtual void startExpandingMacro(unsigned offset,
|
||||
const Macro ¯o,
|
||||
const QByteArray &originalText,
|
||||
bool inCondition,
|
||||
const QVector<MacroArgumentReference> &actuals);
|
||||
virtual void stopExpandingMacro(unsigned offset, const Macro ¯o);
|
||||
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,9 +195,75 @@ 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)
|
||||
{
|
||||
(void) node;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
#ifdef ICHECK_BUILD
|
||||
void QPropertyDeclarationAST::accept0(ASTVisitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
}
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void QEnumDeclarationAST::accept0(ASTVisitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
}
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void QFlagsDeclarationAST::accept0(ASTVisitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
}
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void QDeclareFlagsDeclarationAST::accept0(ASTVisitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
}
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
#endif
|
||||
|
||||
void AsmDefinitionAST::accept0(ASTVisitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
|
||||
@@ -103,6 +103,12 @@ public:
|
||||
virtual void postVisit(AST *) {}
|
||||
|
||||
virtual bool visit(AccessDeclarationAST *) { return true; }
|
||||
#ifdef ICHECK_BUILD
|
||||
virtual bool visit(QPropertyDeclarationAST *) { return true; }
|
||||
virtual bool visit(QEnumDeclarationAST *) { return true; }
|
||||
virtual bool visit(QFlagsDeclarationAST *) { return true; }
|
||||
virtual bool visit(QDeclareFlagsDeclarationAST *) { return true; }
|
||||
#endif
|
||||
virtual bool visit(ArrayAccessAST *) { return true; }
|
||||
virtual bool visit(ArrayDeclaratorAST *) { return true; }
|
||||
virtual bool visit(ArrayInitializerAST *) { return true; }
|
||||
@@ -229,6 +235,12 @@ public:
|
||||
virtual bool visit(ObjCSynchronizedStatementAST *) { return true; }
|
||||
|
||||
virtual void endVisit(AccessDeclarationAST *) { }
|
||||
#ifdef ICHECK_BUILD
|
||||
virtual void endVisit(QPropertyDeclarationAST *) { }
|
||||
virtual void endVisit(QEnumDeclarationAST *) { }
|
||||
virtual void endVisit(QFlagsDeclarationAST *) { }
|
||||
virtual void endVisit(QDeclareFlagsDeclarationAST *) { }
|
||||
#endif
|
||||
virtual void endVisit(ArrayAccessAST *) { }
|
||||
virtual void endVisit(ArrayDeclaratorAST *) { }
|
||||
virtual void endVisit(ArrayInitializerAST *) { }
|
||||
|
||||
@@ -60,6 +60,12 @@ class ASTVisitor;
|
||||
class ASTMatcher;
|
||||
|
||||
class AccessDeclarationAST;
|
||||
#ifdef ICHECK_BUILD
|
||||
class QPropertyDeclarationAST;
|
||||
class QEnumDeclarationAST;
|
||||
class QFlagsDeclarationAST;
|
||||
class QDeclareFlagsDeclarationAST;
|
||||
#endif
|
||||
class ArrayAccessAST;
|
||||
class ArrayDeclaratorAST;
|
||||
class ArrayInitializerAST;
|
||||
|
||||
@@ -60,7 +60,11 @@
|
||||
# elif defined(CPLUSPLUS_BUILD_STATIC_LIB)
|
||||
# define CPLUSPLUS_EXPORT
|
||||
# else
|
||||
# define CPLUSPLUS_EXPORT Q_DECL_IMPORT
|
||||
# ifdef ICHECK_BUILD
|
||||
# define CPLUSPLUS_EXPORT
|
||||
# else
|
||||
# define CPLUSPLUS_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
# define CPLUSPLUS_EXPORT
|
||||
|
||||
@@ -170,6 +170,9 @@ bool CheckDeclaration::visit(SimpleDeclarationAST *ast)
|
||||
|
||||
const bool isQ_SLOT = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SLOT;
|
||||
const bool isQ_SIGNAL = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SIGNAL;
|
||||
#ifdef ICHECK_BUILD
|
||||
const bool isQ_INVOKABLE = (ast->invoke_token > 0);
|
||||
#endif
|
||||
|
||||
List<Declaration *> **decl_it = &ast->symbols;
|
||||
for (DeclaratorListAST *it = ast->declarator_list; it; it = it->next) {
|
||||
@@ -196,6 +199,10 @@ bool CheckDeclaration::visit(SimpleDeclarationAST *ast)
|
||||
fun->setMethodKey(Function::SignalMethod);
|
||||
else if (isQ_SLOT)
|
||||
fun->setMethodKey(Function::SlotMethod);
|
||||
#ifdef ICHECK_BUILD
|
||||
else if (isQ_INVOKABLE)
|
||||
fun->setInvokable(true);
|
||||
#endif
|
||||
fun->setVisibility(semantic()->currentVisibility());
|
||||
} else if (semantic()->currentMethodKey() != Function::NormalMethod) {
|
||||
translationUnit()->warning(ast->firstToken(),
|
||||
@@ -259,6 +266,28 @@ bool CheckDeclaration::visit(AccessDeclarationAST *ast)
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef ICHECK_BUILD
|
||||
bool CheckDeclaration::visit(QPropertyDeclarationAST *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CheckDeclaration::visit(QEnumDeclarationAST *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CheckDeclaration::visit(QFlagsDeclarationAST *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CheckDeclaration::visit(QDeclareFlagsDeclarationAST *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool CheckDeclaration::visit(AsmDefinitionAST *)
|
||||
{
|
||||
return false;
|
||||
@@ -316,11 +345,18 @@ bool CheckDeclaration::visit(FunctionDefinitionAST *ast)
|
||||
|
||||
const bool isQ_SLOT = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SLOT;
|
||||
const bool isQ_SIGNAL = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SIGNAL;
|
||||
#ifdef ICHECK_BUILD
|
||||
const bool isQ_INVOKABLE = (ast->invoke_token > 0);
|
||||
#endif
|
||||
|
||||
if (isQ_SIGNAL)
|
||||
fun->setMethodKey(Function::SignalMethod);
|
||||
else if (isQ_SLOT)
|
||||
fun->setMethodKey(Function::SlotMethod);
|
||||
#ifdef ICHECK_BUILD
|
||||
else if (isQ_INVOKABLE)
|
||||
fun->setInvokable(true);
|
||||
#endif
|
||||
|
||||
checkFunctionArguments(fun);
|
||||
|
||||
|
||||
@@ -77,6 +77,12 @@ protected:
|
||||
virtual bool visit(SimpleDeclarationAST *ast);
|
||||
virtual bool visit(EmptyDeclarationAST *ast);
|
||||
virtual bool visit(AccessDeclarationAST *ast);
|
||||
#ifdef ICHECK_BUILD
|
||||
virtual bool visit(QPropertyDeclarationAST *ast);
|
||||
virtual bool visit(QEnumDeclarationAST *ast);
|
||||
virtual bool visit(QFlagsDeclarationAST *ast);
|
||||
virtual bool visit(QDeclareFlagsDeclarationAST *ast);
|
||||
#endif
|
||||
virtual bool visit(AsmDefinitionAST *ast);
|
||||
virtual bool visit(ExceptionDeclarationAST *ast);
|
||||
virtual bool visit(FunctionDefinitionAST *ast);
|
||||
|
||||
@@ -718,6 +718,30 @@ static inline int classify7(const char *s, bool q) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef ICHECK_BUILD
|
||||
else if (s[2] == 'E') {
|
||||
if (s[3] == 'N') {
|
||||
if (s[4] == 'U') {
|
||||
if (s[5] == 'M') {
|
||||
if (s[6] == 'S') {
|
||||
return T_Q_ENUMS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (s[2] == 'F') {
|
||||
if (s[3] == 'L') {
|
||||
if (s[4] == 'A') {
|
||||
if (s[5] == 'G') {
|
||||
if (s[6] == 'S') {
|
||||
return T_Q_FLAGS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return T_IDENTIFIER;
|
||||
@@ -1079,6 +1103,29 @@ static inline int classify10(const char *s, bool) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef ICHECK_BUILD
|
||||
else if (s[0] == 'Q') {
|
||||
if (s[1] == '_') {
|
||||
if (s[2] == 'P') {
|
||||
if (s[3] == 'R') {
|
||||
if (s[4] == 'O') {
|
||||
if (s[5] == 'P') {
|
||||
if (s[6] == 'E') {
|
||||
if (s[7] == 'R') {
|
||||
if (s[8] == 'T') {
|
||||
if (s[9] == 'Y') {
|
||||
return T_Q_PROPERTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return T_IDENTIFIER;
|
||||
}
|
||||
|
||||
@@ -1129,6 +1176,31 @@ static inline int classify11(const char *s, bool) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef ICHECK_BUILD
|
||||
else if (s[0] == 'Q') {
|
||||
if (s[1] == '_') {
|
||||
if (s[2] == 'I') {
|
||||
if (s[3] == 'N') {
|
||||
if (s[4] == 'V') {
|
||||
if (s[5] == 'O') {
|
||||
if (s[6] == 'K') {
|
||||
if (s[7] == 'A') {
|
||||
if (s[8] == 'B') {
|
||||
if (s[9] == 'L') {
|
||||
if (s[10] == 'E') {
|
||||
return T_Q_INVOKABLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return T_IDENTIFIER;
|
||||
}
|
||||
|
||||
@@ -1217,6 +1289,43 @@ static inline int classify13(const char *s, bool) {
|
||||
return T_IDENTIFIER;
|
||||
}
|
||||
|
||||
#ifdef ICHECK_BUILD
|
||||
static inline int classify15(const char *s, bool) {
|
||||
if (s[0] == 'Q') {
|
||||
if (s[1] == '_') {
|
||||
if (s[2] == 'D') {
|
||||
if (s[3] == 'E') {
|
||||
if (s[4] == 'C') {
|
||||
if (s[5] == 'L') {
|
||||
if (s[6] == 'A') {
|
||||
if (s[7] == 'R') {
|
||||
if (s[8] == 'E') {
|
||||
if (s[9] == '_') {
|
||||
if (s[10] == 'F') {
|
||||
if (s[11] == 'L') {
|
||||
if (s[12] == 'A') {
|
||||
if (s[13] == 'G') {
|
||||
if (s[14] == 'S') {
|
||||
return T_Q_DECLARE_FLAGS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return T_IDENTIFIER;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int classify16(const char *s, bool) {
|
||||
if (s[0] == 'r') {
|
||||
if (s[1] == 'e') {
|
||||
@@ -1268,6 +1377,9 @@ int Lexer::classify(const char *s, int n, bool q) {
|
||||
case 11: return classify11(s, q);
|
||||
case 12: return classify12(s, q);
|
||||
case 13: return classify13(s, q);
|
||||
#ifdef ICHECK_BUILD
|
||||
case 15: return classify15(s, q);
|
||||
#endif
|
||||
case 16: return classify16(s, q);
|
||||
default: return T_IDENTIFIER;
|
||||
} // switch
|
||||
|
||||
@@ -54,6 +54,9 @@
|
||||
#include "Literals.h"
|
||||
#include "ObjectiveCTypeQualifiers.h"
|
||||
#include <cstdio> // for putchar
|
||||
#ifdef ICHECK_BUILD
|
||||
# include <QString>
|
||||
#endif
|
||||
|
||||
#define CPLUSPLUS_NO_DEBUG_RULE
|
||||
|
||||
@@ -1651,6 +1654,158 @@ bool Parser::parseAccessDeclaration(DeclarationAST *&node)
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef ICHECK_BUILD
|
||||
bool Parser::parseQPropertyDeclaration(DeclarationAST *&node)
|
||||
{
|
||||
/*
|
||||
Q_PROPERTY(type name
|
||||
READ getFunction
|
||||
[WRITE setFunction]
|
||||
[RESET resetFunction]
|
||||
[NOTIFY notifySignal]
|
||||
[DESIGNABLE bool]
|
||||
[SCRIPTABLE bool]
|
||||
[STORED bool]
|
||||
[USER bool]
|
||||
[CONSTANT]
|
||||
[FINAL])*/
|
||||
DEBUG_THIS_RULE();
|
||||
if (LA() == T_Q_PROPERTY) {
|
||||
QPropertyDeclarationAST *ast = new (_pool)QPropertyDeclarationAST;
|
||||
ast->property_specifier_token = consumeToken();
|
||||
if(LA() == T_LPAREN){
|
||||
ast->lparen_token = consumeToken();
|
||||
QString tokenstr;
|
||||
tokenstr = tok().spell();
|
||||
//read the type and the name of the type
|
||||
if(tokenstr != "READ" ){
|
||||
ast->type_token = consumeToken();
|
||||
tokenstr = tok().spell();
|
||||
}
|
||||
if(tokenstr != "READ" ){
|
||||
ast->type_name_token = consumeToken();
|
||||
tokenstr = tok().spell();
|
||||
}
|
||||
unsigned fctdefinition = 0;
|
||||
unsigned fctname = 0;
|
||||
for(int i = 0; i < 18; i++){
|
||||
if(cursor() < _translationUnit->tokenCount() - 1){
|
||||
if(LA() == T_RPAREN){
|
||||
ast->rparen_token = consumeToken();
|
||||
break;
|
||||
}
|
||||
tokenstr = tok().spell();
|
||||
fctdefinition = consumeToken();
|
||||
fctname = consumeToken();
|
||||
if(tokenstr == "READ"){
|
||||
ast->read_token = fctdefinition;
|
||||
ast->read_function_token = fctname;
|
||||
}
|
||||
else if(tokenstr == "WRITE"){
|
||||
ast->write_token = fctdefinition;
|
||||
ast->write_function_token = fctname;
|
||||
}
|
||||
else if(tokenstr == "RESET"){
|
||||
ast->reset_token = fctdefinition;
|
||||
ast->reset_function_token = fctname;
|
||||
}
|
||||
else if(tokenstr == "NOTIFY"){
|
||||
ast->notify_token = fctdefinition;
|
||||
ast->notify_function_token = fctname;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node = ast;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Parser::parseQEnumDeclaration(DeclarationAST *&node)
|
||||
{
|
||||
/*Q_ENUMS(ConnectionState)*/
|
||||
DEBUG_THIS_RULE();
|
||||
if (LA() == T_Q_ENUMS) {
|
||||
QEnumDeclarationAST *ast = new (_pool)QEnumDeclarationAST;
|
||||
ast->enum_specifier_token = consumeToken();
|
||||
EnumeratorListAST** enumerator_list_ptr;
|
||||
enumerator_list_ptr = &ast->enumerator_list;
|
||||
|
||||
if(LA() == T_LPAREN){
|
||||
ast->lparen_token = consumeToken();
|
||||
while(LA() != T_EOF_SYMBOL && LA() != T_RPAREN){
|
||||
*enumerator_list_ptr = new (_pool) EnumeratorListAST;
|
||||
EnumeratorAST *pdecl = new (_pool) EnumeratorAST;
|
||||
pdecl->identifier_token = consumeToken();
|
||||
(*enumerator_list_ptr)->value = pdecl;
|
||||
enumerator_list_ptr = &(*enumerator_list_ptr)->next;
|
||||
if (LA() == T_COMMA)
|
||||
consumeToken();
|
||||
}
|
||||
if(LA() == T_RPAREN)
|
||||
ast->rparen_token = consumeToken();
|
||||
}
|
||||
node = ast;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Parser::parseQFlags(DeclarationAST *&node)
|
||||
{
|
||||
/*Q_FLAGS(enum1 enum2 flags1)*/
|
||||
DEBUG_THIS_RULE();
|
||||
if (LA() == T_Q_FLAGS) {
|
||||
QFlagsDeclarationAST *ast = new (_pool)QFlagsDeclarationAST;
|
||||
ast->flags_specifier_token = consumeToken();
|
||||
EnumeratorListAST** enumerator_list_ptr;
|
||||
enumerator_list_ptr = &ast->enumerator_list;
|
||||
if(LA() == T_LPAREN){
|
||||
ast->lparen_token = consumeToken();
|
||||
while(LA() != T_EOF_SYMBOL && LA() != T_RPAREN){
|
||||
*enumerator_list_ptr = new (_pool) EnumeratorListAST;
|
||||
EnumeratorAST *pdecl = new (_pool) EnumeratorAST;
|
||||
pdecl->identifier_token = consumeToken();
|
||||
(*enumerator_list_ptr)->value = pdecl;
|
||||
enumerator_list_ptr = &(*enumerator_list_ptr)->next;
|
||||
if (LA() == T_COMMA)
|
||||
consumeToken();
|
||||
}
|
||||
if(LA() == T_RPAREN)
|
||||
ast->rparen_token = consumeToken();
|
||||
}
|
||||
node = ast;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Parser::parseQDeclareFlags(DeclarationAST *&node)
|
||||
{
|
||||
/*Q_DECLARE_FLAGS(flag enum)*/
|
||||
DEBUG_THIS_RULE();
|
||||
if (LA() == T_Q_DECLARE_FLAGS) {
|
||||
QDeclareFlagsDeclarationAST *ast = new (_pool)QDeclareFlagsDeclarationAST;
|
||||
ast->declareflags_specifier_token = consumeToken();
|
||||
if(LA() == T_LPAREN){
|
||||
ast->lparen_token = consumeToken();
|
||||
if(LA() != T_EOF_SYMBOL)
|
||||
ast->flag_token = consumeToken();
|
||||
if(LA() == T_COMMA && LA() != T_EOF_SYMBOL)
|
||||
consumeToken();
|
||||
if(LA() != T_EOF_SYMBOL)
|
||||
ast->enum_token = consumeToken();
|
||||
if(LA() != T_EOF_SYMBOL && LA() == T_RPAREN)
|
||||
ast->rparen_token = consumeToken();
|
||||
}
|
||||
node = ast;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool Parser::parseMemberSpecification(DeclarationAST *&node)
|
||||
{
|
||||
DEBUG_THIS_RULE();
|
||||
@@ -1670,6 +1825,20 @@ bool Parser::parseMemberSpecification(DeclarationAST *&node)
|
||||
case T_PRIVATE:
|
||||
return parseAccessDeclaration(node);
|
||||
|
||||
#ifdef ICHECK_BUILD
|
||||
case T_Q_PROPERTY:
|
||||
return parseQPropertyDeclaration(node);
|
||||
|
||||
case T_Q_ENUMS:
|
||||
return parseQEnumDeclaration(node);
|
||||
|
||||
case T_Q_FLAGS:
|
||||
return parseQFlags(node);
|
||||
|
||||
case T_Q_DECLARE_FLAGS:
|
||||
return parseQDeclareFlags(node);
|
||||
#endif
|
||||
|
||||
default:
|
||||
return parseSimpleDeclaration(node, /*acceptStructDeclarator=*/true);
|
||||
} // switch
|
||||
@@ -2780,6 +2949,11 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node,
|
||||
unsigned qt_invokable_token = 0;
|
||||
if (acceptStructDeclarator && (LA() == T_Q_SIGNAL || LA() == T_Q_SLOT))
|
||||
qt_invokable_token = consumeToken();
|
||||
#ifdef ICHECK_BUILD
|
||||
unsigned invoke_token = 0;
|
||||
if (LA() == T_Q_INVOKABLE)
|
||||
invoke_token = consumeToken();
|
||||
#endif
|
||||
|
||||
// parse a simple declaration, a function definition,
|
||||
// or a contructor declaration.
|
||||
@@ -2907,6 +3081,9 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node,
|
||||
}
|
||||
SimpleDeclarationAST *ast = new (_pool) SimpleDeclarationAST;
|
||||
ast->qt_invokable_token = qt_invokable_token;
|
||||
#ifdef ICHECK_BUILD
|
||||
ast->invoke_token = invoke_token;
|
||||
#endif
|
||||
ast->decl_specifier_list = decl_specifier_seq;
|
||||
ast->declarator_list = declarator_list;
|
||||
match(T_SEMICOLON, &ast->semicolon_token);
|
||||
@@ -2936,6 +3113,9 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node,
|
||||
if (LA() == T_LBRACE || hasCtorInitializer) {
|
||||
FunctionDefinitionAST *ast = new (_pool) FunctionDefinitionAST;
|
||||
ast->qt_invokable_token = qt_invokable_token;
|
||||
#ifdef ICHECK_BUILD
|
||||
ast->invoke_token = invoke_token;
|
||||
#endif
|
||||
ast->decl_specifier_list = decl_specifier_seq;
|
||||
ast->declarator = firstDeclarator;
|
||||
ast->ctor_initializer = ctor_initializer;
|
||||
@@ -2945,6 +3125,9 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node,
|
||||
} else if (LA() == T_TRY) {
|
||||
FunctionDefinitionAST *ast = new (_pool) FunctionDefinitionAST;
|
||||
ast->qt_invokable_token = qt_invokable_token;
|
||||
#ifdef ICHECK_BUILD
|
||||
ast->invoke_token = invoke_token;
|
||||
#endif
|
||||
ast->decl_specifier_list = decl_specifier_seq;
|
||||
ast->declarator = firstDeclarator;
|
||||
ast->ctor_initializer = ctor_initializer;
|
||||
|
||||
@@ -78,6 +78,12 @@ public:
|
||||
bool parseAbstractDeclarator(DeclaratorAST *&node);
|
||||
bool parseEmptyDeclaration(DeclarationAST *&node);
|
||||
bool parseAccessDeclaration(DeclarationAST *&node);
|
||||
#ifdef ICHECK_BUILD
|
||||
bool parseQPropertyDeclaration(DeclarationAST *&node);
|
||||
bool parseQEnumDeclaration(DeclarationAST *&node);
|
||||
bool parseQFlags(DeclarationAST *&node);
|
||||
bool parseQDeclareFlags(DeclarationAST *&node);
|
||||
#endif
|
||||
bool parseAdditiveExpression(ExpressionAST *&node);
|
||||
bool parseAndExpression(ExpressionAST *&node);
|
||||
bool parseAsmDefinition(DeclarationAST *&node);
|
||||
|
||||
@@ -221,6 +221,10 @@ bool Function::isEqualTo(const Type *other) const
|
||||
return false;
|
||||
else if (isVolatile() != o->isVolatile())
|
||||
return false;
|
||||
#ifdef ICHECK_BUILD
|
||||
else if (isInvokable() != o->isInvokable())
|
||||
return false;
|
||||
#endif
|
||||
|
||||
const Name *l = identity();
|
||||
const Name *r = o->identity();
|
||||
@@ -240,6 +244,35 @@ bool Function::isEqualTo(const Type *other) const
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef ICHECK_BUILD
|
||||
bool Function::isEqualTo(const Function* fct, bool ignoreName/* = false*/) const
|
||||
{
|
||||
if(!ignoreName)
|
||||
return isEqualTo((Type*)fct);
|
||||
|
||||
if (! fct)
|
||||
return false;
|
||||
else if (isConst() != fct->isConst())
|
||||
return false;
|
||||
else if (isVolatile() != fct->isVolatile())
|
||||
return false;
|
||||
else if (isInvokable() != fct->isInvokable())
|
||||
return false;
|
||||
|
||||
if (_arguments->symbolCount() != fct->_arguments->symbolCount())
|
||||
return false;
|
||||
else if (! _returnType.isEqualTo(fct->_returnType))
|
||||
return false;
|
||||
for (unsigned i = 0; i < _arguments->symbolCount(); ++i) {
|
||||
Symbol *l = _arguments->symbolAt(i);
|
||||
Symbol *r = fct->_arguments->symbolAt(i);
|
||||
if (! l->type().isEqualTo(r->type()))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void Function::accept0(TypeVisitor *visitor)
|
||||
{ visitor->visit(this); }
|
||||
|
||||
@@ -316,6 +349,16 @@ bool Function::isPureVirtual() const
|
||||
void Function::setPureVirtual(bool isPureVirtual)
|
||||
{ f._isPureVirtual = isPureVirtual; }
|
||||
|
||||
#ifdef ICHECK_BUILD
|
||||
|
||||
bool Function::isInvokable() const
|
||||
{ return f._isInvokable == 1; }
|
||||
|
||||
void Function::setInvokable(bool isInvokable)
|
||||
{ f._isInvokable = isInvokable; }
|
||||
|
||||
#endif
|
||||
|
||||
bool Function::isAmbiguous() const
|
||||
{ return f._isAmbiguous; }
|
||||
|
||||
|
||||
@@ -350,6 +350,14 @@ public:
|
||||
bool isPureVirtual() const;
|
||||
void setPureVirtual(bool isPureVirtual);
|
||||
|
||||
#ifdef ICHECK_BUILD
|
||||
|
||||
bool isInvokable() const;
|
||||
void setInvokable(bool isInvokable);
|
||||
bool isEqualTo(const Function* fct, bool ignoreName = false) const;
|
||||
|
||||
#endif
|
||||
|
||||
// Symbol's interface
|
||||
virtual FullySpecifiedType type() const;
|
||||
|
||||
@@ -387,6 +395,9 @@ private:
|
||||
unsigned _isVolatile: 1;
|
||||
unsigned _isAmbiguous: 1;
|
||||
unsigned _methodKey: 3;
|
||||
#ifdef ICHECK_BUILD
|
||||
unsigned _isInvokable: 1;
|
||||
#endif
|
||||
};
|
||||
union {
|
||||
unsigned _flags;
|
||||
|
||||
@@ -91,7 +91,11 @@ static const char *token_names[] = {
|
||||
("@protected"), ("@protocol"), ("@public"), ("@required"), ("@selector"),
|
||||
("@synchronized"), ("@synthesize"), ("@throw"), ("@try"),
|
||||
|
||||
("SIGNAL"), ("SLOT"), ("Q_SIGNAL"), ("Q_SLOT"), ("signals"), ("slots"), ("Q_FOREACH"), ("Q_D"), ("Q_Q")
|
||||
("SIGNAL"), ("SLOT"), ("Q_SIGNAL"), ("Q_SLOT"), ("signals"), ("slots"),
|
||||
("Q_FOREACH"), ("Q_D"), ("Q_Q"),
|
||||
#ifdef ICHECK_BUILD
|
||||
("Q_INVOKABLE"), ("Q_PROPERTY"), ("Q_ENUMS"), ("Q_FLAGS"), ("Q_DECLARE_FLAGS")
|
||||
#endif
|
||||
};
|
||||
|
||||
Token::Token() :
|
||||
|
||||
@@ -238,9 +238,16 @@ enum Kind {
|
||||
T_Q_FOREACH,
|
||||
T_Q_D,
|
||||
T_Q_Q,
|
||||
|
||||
#ifndef ICHECK_BUILD
|
||||
T_LAST_KEYWORD = T_Q_Q,
|
||||
|
||||
#else
|
||||
T_Q_INVOKABLE,
|
||||
T_Q_PROPERTY,
|
||||
T_Q_ENUMS,
|
||||
T_Q_FLAGS,
|
||||
T_Q_DECLARE_FLAGS,
|
||||
T_LAST_KEYWORD = T_Q_DECLARE_FLAGS,
|
||||
#endif
|
||||
// aliases
|
||||
T_OR = T_PIPE_PIPE,
|
||||
T_AND = T_AMPER_AMPER,
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# ----------------------------------------------------
|
||||
# This file is generated by the Qt Visual Studio Add-in.
|
||||
# ------------------------------------------------------
|
||||
|
||||
SOURCES += ./main.cpp
|
||||
@@ -0,0 +1,6 @@
|
||||
TEMPLATE = subdirs
|
||||
CONFIG += ordered
|
||||
|
||||
SUBDIRS = \
|
||||
ICheckLib \
|
||||
ICheckApp
|
||||
@@ -0,0 +1,23 @@
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2010-01-18T15:27:35
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT -= gui
|
||||
|
||||
TARGET = ICheckApp
|
||||
CONFIG += console
|
||||
CONFIG -= app_bundle
|
||||
|
||||
TEMPLATE = app
|
||||
|
||||
INCLUDEPATH += ../ICheckLib
|
||||
CONFIG(debug, debug|release){
|
||||
LIBS += -L../ICheckLib/debug -lICheckLibd
|
||||
}
|
||||
else {
|
||||
LIBS += -L../ICheckLib/release -lICheckLib
|
||||
}
|
||||
|
||||
SOURCES += main.cpp
|
||||
@@ -0,0 +1,129 @@
|
||||
#include "ichecklib.h"
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <iostream>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QProcess>
|
||||
|
||||
using namespace std;
|
||||
|
||||
QStringList getQTIncludePath()
|
||||
{
|
||||
QStringList ret;
|
||||
QStringList processevironment = QProcess::systemEnvironment();
|
||||
foreach(QString item, processevironment){
|
||||
if(item.indexOf("QTDIR=") == 0){
|
||||
QString qtpath = item.remove("QTDIR=");
|
||||
ret << qtpath + "\\include\\QtCore";
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
if(argc == 3){
|
||||
try{
|
||||
//Extract the file name and path from the arguments
|
||||
QString interfaceHeaderFile = argv[1];
|
||||
QString checkHeaderFile = argv[2];
|
||||
QString curpath = QDir::currentPath();
|
||||
//Create FileInfos for the header files
|
||||
QFile ifile(interfaceHeaderFile);
|
||||
if (!ifile.exists()){
|
||||
QString err = "File does not exist: " + interfaceHeaderFile;
|
||||
throw err;
|
||||
}
|
||||
QFile chfile(checkHeaderFile);
|
||||
if (!chfile.exists()){
|
||||
QString err = "File does not exist: " + checkHeaderFile;
|
||||
throw err;
|
||||
}
|
||||
QFileInfo iFileInfo(ifile);
|
||||
QFileInfo chFileInfo(chfile);
|
||||
|
||||
//Now create a list of the include path
|
||||
QString chIncludepath = chFileInfo.absolutePath();
|
||||
QStringList chIncludepathlist;
|
||||
chIncludepathlist << chIncludepath;
|
||||
chIncludepathlist << getQTIncludePath();
|
||||
|
||||
QString iIncludepath = iFileInfo.absolutePath();
|
||||
QStringList iIncludepathlist;
|
||||
iIncludepathlist << iIncludepath;
|
||||
|
||||
//Create a list of all the soucre files they need to be parsed.
|
||||
//In our case it is just the header file
|
||||
QStringList chFilelist;
|
||||
chFilelist << chFileInfo.filePath();
|
||||
|
||||
QStringList iFilelist;
|
||||
iFilelist << iFileInfo.filePath();
|
||||
|
||||
ICheckLib i_ichecklib;
|
||||
i_ichecklib.ParseHeader(iIncludepathlist, iFilelist);
|
||||
|
||||
ICheckLib ichecklib;
|
||||
ichecklib.ParseHeader(chIncludepathlist, chFilelist);
|
||||
|
||||
if(!ichecklib.check(i_ichecklib)){
|
||||
cout << "Folowing interface items are missing:" << endl;
|
||||
QStringList errorlist = ichecklib.getErrorMsg();
|
||||
foreach(QString msg, errorlist){
|
||||
cout << (const char *)msg.toLatin1() << endl;
|
||||
}
|
||||
ret = -1;
|
||||
}
|
||||
else
|
||||
cout << "Interface is full defined.";
|
||||
|
||||
/*
|
||||
//Parse the interface header
|
||||
CPlusPlus::ParseManager* iParseManager = new CPlusPlus::ParseManager();
|
||||
iParseManager->setIncludePath(iIncludepathlist);
|
||||
iParseManager->parse(iFilelist);
|
||||
|
||||
//Parse the header that needs to be compared against the interface header
|
||||
CPlusPlus::ParseManager* chParseManager = new CPlusPlus::ParseManager();
|
||||
chIncludepathlist << getQTIncludePath();
|
||||
chParseManager->setIncludePath(chIncludepathlist);
|
||||
chParseManager->parse(chFilelist);
|
||||
|
||||
if(!chParseManager->checkAllMetadatas(iParseManager)){
|
||||
cout << "Folowing interface items are missing:" << endl;
|
||||
QStringList errorlist = chParseManager->getErrorMsg();
|
||||
foreach(QString msg, errorlist){
|
||||
cout << (const char *)msg.toLatin1() << endl;
|
||||
}
|
||||
ret = -1;
|
||||
}
|
||||
else
|
||||
cout << "Interface is full defined.";
|
||||
|
||||
delete iParseManager;
|
||||
delete chParseManager;
|
||||
*/
|
||||
}
|
||||
catch (QString msg)
|
||||
{
|
||||
cout << endl << "Error:" << endl;
|
||||
cout << (const char *)msg.toLatin1();
|
||||
ret = -2;
|
||||
}
|
||||
}
|
||||
else{
|
||||
cout << "CompareHeaderWithHeader.exe";
|
||||
cout << " \"Interface header\"";
|
||||
cout << " \"headerfile to check\"";
|
||||
}
|
||||
|
||||
qDebug() << endl << endl << "return value: " << ret;
|
||||
getchar();
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
# ----------------------------------------------------
|
||||
# This file is generated by the Qt Visual Studio Add-in.
|
||||
# ------------------------------------------------------
|
||||
HEADERS += $$REL_PATH_TO_SRC/shared/cplusplus/Array.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/AST.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/ASTMatcher.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/ASTVisitor.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/CheckDeclaration.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/CheckDeclarator.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/CheckExpression.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/CheckName.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/CheckSpecifier.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/CheckStatement.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Control.h \
|
||||
$$REL_PATH_TO_SRC/plugins/coreplugin/core_global.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/CoreTypes.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/CPlusPlusForwardDeclarations.h \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/CppBindings.h \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/CppDocument.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/DiagnosticClient.h \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/FastPreprocessor.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/FullySpecifiedType.h \
|
||||
./ichecklib.h \
|
||||
./ICheckLib_global.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Lexer.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Literals.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/LiteralTable.h \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/Macro.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/MemoryPool.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Name.h \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/NamePrettyPrinter.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Names.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/NameVisitor.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/ObjectiveCTypeQualifiers.h \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/Overview.h \
|
||||
./ParseManager.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Parser.h \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/pp-cctype.h \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/pp-engine.h \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/pp-macro-expander.h \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/pp-scanner.h \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/pp.h \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/PreprocessorClient.h \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/PreprocessorEnvironment.h \
|
||||
$$REL_PATH_TO_SRC/libs/utils/qtcassert.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Scope.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Semantic.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/SemanticCheck.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Symbol.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Symbols.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/SymbolVisitor.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Token.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/TranslationUnit.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Type.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/TypeMatcher.h \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/TypePrettyPrinter.h \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/TypeVisitor.h
|
||||
SOURCES += $$REL_PATH_TO_SRC/shared/cplusplus/Array.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/AST.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/ASTMatch0.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/ASTMatcher.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/ASTVisit.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/ASTVisitor.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/CheckDeclaration.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/CheckDeclarator.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/CheckExpression.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/CheckName.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/CheckSpecifier.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/CheckStatement.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Control.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/CoreTypes.cpp \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/CppBindings.cpp \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/CppDocument.cpp \
|
||||
$$REL_PATH_TO_SRC/plugins/cpptools/cppmodelmanager.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/DiagnosticClient.cpp \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/FastPreprocessor.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/FullySpecifiedType.cpp \
|
||||
./ichecklib.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Keywords.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Lexer.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Literals.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/LiteralTable.cpp \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/Macro.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/MemoryPool.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Name.cpp \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/NamePrettyPrinter.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Names.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/NameVisitor.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/ObjectiveCAtKeywords.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/ObjectiveCTypeQualifiers.cpp \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/Overview.cpp \
|
||||
./ParseManager.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Parser.cpp \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/pp-engine.cpp \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/pp-macro-expander.cpp \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/pp-scanner.cpp \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/PreprocessorClient.cpp \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/PreprocessorEnvironment.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Scope.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Semantic.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/SemanticCheck.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Symbol.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Symbols.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/SymbolVisitor.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Token.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/TranslationUnit.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/Type.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/TypeMatcher.cpp \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus/TypePrettyPrinter.cpp \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus/TypeVisitor.cpp
|
||||
@@ -0,0 +1,36 @@
|
||||
REL_PATH_TO_SRC = ../../../
|
||||
|
||||
TEMPLATE = lib
|
||||
CONFIG += debug
|
||||
|
||||
CONFIG(debug, debug|release){
|
||||
TARGET = ICheckLibd
|
||||
DESTDIR = ./debug
|
||||
DLLDESTDIR = ../ICheckApp/debug
|
||||
MOC_DIR += ./debug/GeneratedFiles
|
||||
OBJECTS_DIR += ./debug
|
||||
INCLUDEPATH += ./ \
|
||||
./debug/GeneratedFiles \
|
||||
$$REL_PATH_TO_SRC/plugins \
|
||||
$$REL_PATH_TO_SRC/libs \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus \
|
||||
$(QTDIR)
|
||||
}
|
||||
else {
|
||||
TARGET = ICheckLib
|
||||
DESTDIR = ./release
|
||||
DLLDESTDIR = ../ICheckApp/release
|
||||
MOC_DIR += ./release/GeneratedFiles
|
||||
OBJECTS_DIR += ./release
|
||||
INCLUDEPATH += ./ \
|
||||
./release/GeneratedFiles \
|
||||
$$REL_PATH_TO_SRC/plugins \
|
||||
$$REL_PATH_TO_SRC/libs \
|
||||
$$REL_PATH_TO_SRC/shared/cplusplus \
|
||||
$$REL_PATH_TO_SRC/libs/cplusplus \
|
||||
$(QTDIR)
|
||||
}
|
||||
|
||||
DEFINES += ICHECKLIB_LIBRARY ICHECK_BUILD
|
||||
include(ICheckLib.pri)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,300 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
** Description:
|
||||
**
|
||||
** The ParseManager parses and compares to different header files
|
||||
** of its metadata. This can be used for checking if an Interface
|
||||
** is implemented complete.
|
||||
**
|
||||
** How to use it:
|
||||
**
|
||||
** //Parse the interface header
|
||||
** ParseManager* iParseManager = new ParseManager();
|
||||
** iParseManager->setIncludePath(iIncludepathlist);
|
||||
** iParseManager->parse(iFilelist);
|
||||
**
|
||||
** //Parse the header that needs to be compared against the interface header
|
||||
** ParseManager* chParseManager = new ParseManager();
|
||||
** chIncludepathlist << getQTIncludePath();
|
||||
** chParseManager->setIncludePath(chIncludepathlist);
|
||||
** chParseManager->parse(chFilelist);
|
||||
**
|
||||
** if(!chParseManager->checkAllMetadatas(iParseManager)){
|
||||
** cout << "Folowing interface items are missing:" << endl;
|
||||
** QStringList errorlist = chParseManager->getErrorMsg();
|
||||
** foreach(QString msg, errorlist){
|
||||
** cout << (const char *)msg.toLatin1() << endl;
|
||||
** }
|
||||
** return -1;
|
||||
** }
|
||||
** else
|
||||
** cout << "Interface is full defined.";
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#ifndef PARSEMANAGER_H
|
||||
#define PARSEMANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QList>
|
||||
#include <QFuture>
|
||||
#include <QStringList>
|
||||
#include "cplusplus\CppDocument.h"
|
||||
|
||||
namespace CppTools{
|
||||
namespace Internal{
|
||||
class CppPreprocessor;
|
||||
}
|
||||
}
|
||||
|
||||
namespace CPlusPlus {
|
||||
class TranslationUnit;
|
||||
class AST;
|
||||
class ClassSpecifierAST;
|
||||
class SimpleDeclarationAST;
|
||||
class QPropertyDeclarationAST;
|
||||
class QEnumDeclarationAST;
|
||||
class QFlagsDeclarationAST;
|
||||
class QDeclareFlagsDeclarationAST;
|
||||
class EnumSpecifierAST;
|
||||
class Function;
|
||||
|
||||
class ParseManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
struct CLASSLISTITEM
|
||||
{
|
||||
CPlusPlus::TranslationUnit* trlUnit;
|
||||
ClassSpecifierAST* classspec;
|
||||
};
|
||||
struct CLASSTREE
|
||||
{
|
||||
CLASSLISTITEM* highestlevelclass;
|
||||
QList<CLASSLISTITEM*> classlist;
|
||||
};
|
||||
struct FUNCTIONITEM
|
||||
{
|
||||
const CLASSLISTITEM* highestlevelclass;
|
||||
CPlusPlus::TranslationUnit* trlUnit;
|
||||
ClassSpecifierAST* classAst;
|
||||
QStringList classWichIsNotFound;
|
||||
CPlusPlus::Function* function;
|
||||
SimpleDeclarationAST* ast;
|
||||
|
||||
bool isEqualTo(FUNCTIONITEM* cpfct, bool ignoreName = true);
|
||||
void init()
|
||||
{
|
||||
highestlevelclass = 0;
|
||||
trlUnit = 0;
|
||||
classAst = 0;
|
||||
function = 0;
|
||||
ast = 0;
|
||||
}
|
||||
};
|
||||
struct PROPERTYITEM
|
||||
{
|
||||
const CLASSLISTITEM* highestlevelclass;
|
||||
QStringList classWichIsNotFound;
|
||||
QPropertyDeclarationAST *ast;
|
||||
CPlusPlus::TranslationUnit* trlUnit;
|
||||
bool readdefined;
|
||||
FUNCTIONITEM *readFct;
|
||||
bool writedefined;
|
||||
FUNCTIONITEM *writeFct;
|
||||
bool resetdefined;
|
||||
FUNCTIONITEM *resetFct;
|
||||
bool notifydefined;
|
||||
FUNCTIONITEM *notifyFct;
|
||||
bool foundalldefinedfct;
|
||||
|
||||
bool isEqualTo(PROPERTYITEM* cpppt);
|
||||
void init()
|
||||
{
|
||||
highestlevelclass = 0;
|
||||
ast = 0;
|
||||
trlUnit = 0;
|
||||
readdefined = false;
|
||||
readFct = 0;
|
||||
writedefined = false;
|
||||
writeFct = 0;
|
||||
resetdefined = false;
|
||||
resetFct = 0;
|
||||
notifydefined = false;
|
||||
notifyFct = 0;
|
||||
foundalldefinedfct = false;
|
||||
}
|
||||
};
|
||||
|
||||
struct QENUMITEM
|
||||
{
|
||||
const CLASSLISTITEM* highestlevelclass;
|
||||
CPlusPlus::TranslationUnit* trlUnit;
|
||||
QStringList classWichIsNotFound;
|
||||
QEnumDeclarationAST* ast;
|
||||
//an item in this list will be shown like:
|
||||
//EnumName.EnumItemName.Value
|
||||
//ConnectionState.disconnected.0
|
||||
QStringList values;
|
||||
bool foundallenums;
|
||||
|
||||
bool isEqualTo(QENUMITEM *cpenum);
|
||||
void init()
|
||||
{
|
||||
highestlevelclass = 0;
|
||||
trlUnit = 0;
|
||||
ast = 0;
|
||||
values.clear();
|
||||
foundallenums = true;
|
||||
}
|
||||
};
|
||||
|
||||
struct ENUMITEM
|
||||
{
|
||||
const CLASSLISTITEM* highestlevelclass;
|
||||
CPlusPlus::TranslationUnit* trlUnit;
|
||||
QStringList classWichIsNotFound;
|
||||
EnumSpecifierAST* ast;
|
||||
|
||||
void init()
|
||||
{
|
||||
highestlevelclass = 0;
|
||||
trlUnit = 0;
|
||||
ast = 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct QFLAGITEM
|
||||
{
|
||||
const CLASSLISTITEM* highestlevelclass;
|
||||
CPlusPlus::TranslationUnit* trlUnit;
|
||||
QStringList classWichIsNotFound;
|
||||
QFlagsDeclarationAST* ast;
|
||||
QStringList enumvalues;
|
||||
bool foundallenums;
|
||||
|
||||
bool isEqualTo(QFLAGITEM *cpflag);
|
||||
void init()
|
||||
{
|
||||
highestlevelclass = 0;
|
||||
trlUnit = 0;
|
||||
ast = 0;
|
||||
enumvalues.clear();
|
||||
foundallenums = true;
|
||||
}
|
||||
};
|
||||
|
||||
struct QDECLAREFLAGSITEM
|
||||
{
|
||||
const CLASSLISTITEM* highestlevelclass;
|
||||
CPlusPlus::TranslationUnit* trlUnit;
|
||||
QStringList classWichIsNotFound;
|
||||
QDeclareFlagsDeclarationAST* ast;
|
||||
|
||||
void init()
|
||||
{
|
||||
highestlevelclass = 0;
|
||||
trlUnit = 0;
|
||||
ast = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
ParseManager();
|
||||
virtual ~ParseManager();
|
||||
void setIncludePath(const QStringList &includePath);
|
||||
void parse(const QStringList &sourceFiles);
|
||||
bool checkAllMetadatas(ParseManager* pInterfaceParserManager);
|
||||
CppTools::Internal::CppPreprocessor *getPreProcessor() { return pCppPreprocessor; }
|
||||
QList<CLASSTREE*> CreateClassLists();
|
||||
QStringList getErrorMsg() { return m_errormsgs; }
|
||||
|
||||
private:
|
||||
void parse(CppTools::Internal::CppPreprocessor *preproc, const QStringList &files);
|
||||
void getBaseClasses(const CLASSLISTITEM* pclass, QList<CLASSLISTITEM*> &baseclasslist, const QList<CLASSLISTITEM*> &allclasslist);
|
||||
void getElements(QList<FUNCTIONITEM*> &functionlist
|
||||
, QList<PROPERTYITEM*> &propertylist
|
||||
, QList<QENUMITEM*> &qenumlist
|
||||
, QList<ENUMITEM*> &enumlist
|
||||
, QList<QFLAGITEM*> &qflaglist
|
||||
, QList<QDECLAREFLAGSITEM*> &qdeclareflaglist
|
||||
, const QList<CLASSLISTITEM*> classitems
|
||||
, const CLASSLISTITEM* highestlevelclass);
|
||||
|
||||
//<--- for Metadata functions checks
|
||||
QList<FUNCTIONITEM*> checkMetadataFunctions(const QList<QList<FUNCTIONITEM*> > &classfctlist, const QList<QList<FUNCTIONITEM*> > &iclassfctlist);
|
||||
bool isMetaObjFunction(FUNCTIONITEM* fct);
|
||||
QList<FUNCTIONITEM*> containsAllMetadataFunction(const QList<FUNCTIONITEM*> &classfctlist, const QList<FUNCTIONITEM*> &iclassfctlist);
|
||||
QString getErrorMessage(FUNCTIONITEM* fct);
|
||||
//--->
|
||||
|
||||
//<--- for Q_PROPERTY functions checks
|
||||
QList<PROPERTYITEM*> checkMetadataProperties(const QList<QList<PROPERTYITEM*> > &classproplist
|
||||
, const QList<QList<FUNCTIONITEM*> > &classfctlist
|
||||
, const QList<QList<PROPERTYITEM*> > &iclassproplist
|
||||
, const QList<QList<FUNCTIONITEM*> > &iclassfctlist);
|
||||
void assignPropertyFunctions(PROPERTYITEM* prop, const QList<QList<FUNCTIONITEM*> > &fctlookuplist);
|
||||
QList<PROPERTYITEM*> containsAllPropertyFunction(const QList<PROPERTYITEM*> &classproplist, const QList<PROPERTYITEM*> &iclassproplist);
|
||||
QString getErrorMessage(PROPERTYITEM* ppt);
|
||||
//--->
|
||||
|
||||
//<--- for Q_ENUMS checks
|
||||
QList<QENUMITEM*> checkMetadataEnums(const QList<QList<QENUMITEM*> > &classqenumlist
|
||||
, const QList<QList<ENUMITEM*> > &classenumlist
|
||||
, const QList<QList<QENUMITEM*> > &iclassqenumlist
|
||||
, const QList<QList<ENUMITEM*> > &iclassenumlist);
|
||||
QStringList getEnumValueStringList(ENUMITEM *penum, QString mappedenumname = "");
|
||||
void assignEnumValues(QENUMITEM* qenum, const QList<QList<ENUMITEM*> > &enumlookuplist);
|
||||
QList<QENUMITEM*> containsAllEnums(const QList<QENUMITEM*> &classqenumlist, const QList<QENUMITEM*> &iclassqenumlist);
|
||||
QString getErrorMessage(QENUMITEM* qenum);
|
||||
//--->
|
||||
|
||||
//<--- for QFlags checks --->
|
||||
QList<QFLAGITEM*> checkMetadataFlags(const QList<QList<QFLAGITEM*> > &classqflaglist
|
||||
, const QList<QList<QDECLAREFLAGSITEM*> > &classqdeclareflaglist
|
||||
, const QList<QList<ENUMITEM*> > &classenumlist
|
||||
, const QList<QList<QFLAGITEM*> > &iclassqflaglist
|
||||
, const QList<QList<QDECLAREFLAGSITEM*> > &iclassqdeclareflaglist
|
||||
, const QList<QList<ENUMITEM*> > &iclassenumlist);
|
||||
void assignFlagValues(QFLAGITEM* qflags, const QList<QList<QDECLAREFLAGSITEM*> > &qdeclareflagslookuplist, const QList<QList<ENUMITEM*> > &enumlookuplist);
|
||||
QList<QFLAGITEM*> containsAllFlags(const QList<QFLAGITEM*> &classqflaglist, const QList<QFLAGITEM*> &iclassqflaglist);
|
||||
QString getErrorMessage(QFLAGITEM* pfg);
|
||||
//--->
|
||||
|
||||
private:
|
||||
// cache
|
||||
QStringList m_includePaths;
|
||||
QStringList m_frameworkPaths;
|
||||
QByteArray m_definedMacros;
|
||||
CppTools::Internal::CppPreprocessor* pCppPreprocessor;
|
||||
QString m_strHeaderFile;
|
||||
QStringList m_errormsgs;
|
||||
};
|
||||
}
|
||||
#endif // PARSEMANAGER_H
|
||||
@@ -0,0 +1,60 @@
|
||||
#include "ichecklib.h"
|
||||
#include "ParseManager.h"
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <iostream>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QProcess>
|
||||
|
||||
QStringList getQTIncludePath()
|
||||
{
|
||||
QStringList ret;
|
||||
QStringList processevironment = QProcess::systemEnvironment();
|
||||
foreach(QString item, processevironment){
|
||||
if(item.indexOf("QTDIR=") == 0){
|
||||
QString qtpath = item.remove("QTDIR=");
|
||||
ret << qtpath + "\\include\\QtCore";
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ICheckLib::ICheckLib()
|
||||
: pParseManager(0)
|
||||
{
|
||||
}
|
||||
|
||||
void ICheckLib::ParseHeader(const QStringList& includePath, const QStringList& filelist)
|
||||
{
|
||||
if(pParseManager)
|
||||
delete pParseManager;
|
||||
pParseManager = 0;
|
||||
pParseManager = new CPlusPlus::ParseManager();
|
||||
pParseManager->setIncludePath(includePath);
|
||||
pParseManager->parse(filelist);
|
||||
}
|
||||
|
||||
bool ICheckLib::check(const ICheckLib& ichecklib /*ICheckLib from interface header*/)
|
||||
{
|
||||
if(pParseManager){
|
||||
CPlusPlus::ParseManager* cpparsemanager = ichecklib.pParseManager;
|
||||
return pParseManager->checkAllMetadatas(cpparsemanager);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList ICheckLib::getErrorMsg()
|
||||
{
|
||||
QStringList ret;
|
||||
if(pParseManager){
|
||||
ret.append(pParseManager->getErrorMsg());
|
||||
}
|
||||
else
|
||||
ret << "no file was parsed.";
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef ICHECKLIB_H
|
||||
#define ICHECKLIB_H
|
||||
|
||||
#include <QStringList>
|
||||
#include "ICheckLib_global.h"
|
||||
|
||||
namespace CPlusPlus{
|
||||
class ParseManager;
|
||||
}
|
||||
|
||||
class ICHECKLIBSHARED_EXPORT ICheckLib {
|
||||
public:
|
||||
ICheckLib();
|
||||
void ParseHeader(const QStringList& includePath, const QStringList& filelist);
|
||||
bool check(const ICheckLib& ichecklib /*ICheckLib from interface header*/);
|
||||
QStringList getErrorMsg();
|
||||
private:
|
||||
CPlusPlus::ParseManager* pParseManager;
|
||||
};
|
||||
|
||||
#endif // ICHECKLIB_H
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef ICHECKLIB_GLOBAL_H
|
||||
#define ICHECKLIB_GLOBAL_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#if defined(ICHECKLIB_LIBRARY)
|
||||
# define ICHECKLIBSHARED_EXPORT Q_DECL_EXPORT
|
||||
#else
|
||||
# define ICHECKLIBSHARED_EXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
|
||||
#endif // ICHECKLIB_GLOBAL_H
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
TEMPLATE = subdirs
|
||||
win32:SUBDIRS = qtcdebugger
|
||||
win32:SUBDIRS = qtcdebugger ICheck
|
||||
|
||||
Reference in New Issue
Block a user