summaryrefslogtreecommitdiff
path: root/src/shared/cplusplus
diff options
context:
space:
mode:
authorWolfgang Beck <wolfgang.beck@nokia.com>2010-01-19 15:26:08 +1000
committerWolfgang Beck <wolfgang.beck@nokia.com>2010-01-19 15:26:08 +1000
commit4b3388172904e629fc6f6f1e3a6323e8fe12b97f (patch)
tree098dca6bbe72201050a4d8ec94c008903eb67ed3 /src/shared/cplusplus
parent29b7594b38f3545bb6a5d5ff08542c0e71a30197 (diff)
downloadqt-creator-4b3388172904e629fc6f6f1e3a6323e8fe12b97f.tar.gz
Merge ichecker branch changes into the mainline. New project can be found under src/tools/ICheck
Diffstat (limited to 'src/shared/cplusplus')
-rw-r--r--src/shared/cplusplus/AST.cpp45
-rw-r--r--src/shared/cplusplus/AST.h112
-rw-r--r--src/shared/cplusplus/ASTMatch0.cpp34
-rw-r--r--src/shared/cplusplus/ASTMatcher.cpp66
-rw-r--r--src/shared/cplusplus/ASTMatcher.h6
-rw-r--r--src/shared/cplusplus/ASTVisit.cpp30
-rw-r--r--src/shared/cplusplus/ASTVisitor.h12
-rw-r--r--src/shared/cplusplus/ASTfwd.h6
-rw-r--r--src/shared/cplusplus/CPlusPlusForwardDeclarations.h6
-rw-r--r--src/shared/cplusplus/CheckDeclaration.cpp36
-rw-r--r--src/shared/cplusplus/CheckDeclaration.h6
-rw-r--r--src/shared/cplusplus/Keywords.cpp112
-rw-r--r--src/shared/cplusplus/Parser.cpp183
-rw-r--r--src/shared/cplusplus/Parser.h6
-rw-r--r--src/shared/cplusplus/Symbols.cpp43
-rw-r--r--src/shared/cplusplus/Symbols.h11
-rw-r--r--src/shared/cplusplus/Token.cpp6
-rw-r--r--src/shared/cplusplus/Token.h11
18 files changed, 726 insertions, 5 deletions
diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp
index 084334a9ab..d394fa3694 100644
--- a/src/shared/cplusplus/AST.cpp
+++ b/src/shared/cplusplus/AST.cpp
@@ -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
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index a26384b74f..8bbd9fe989 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -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:
diff --git a/src/shared/cplusplus/ASTMatch0.cpp b/src/shared/cplusplus/ASTMatch0.cpp
index e16c078808..1d329a856a 100644
--- a/src/shared/cplusplus/ASTMatch0.cpp
+++ b/src/shared/cplusplus/ASTMatch0.cpp
@@ -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())
diff --git a/src/shared/cplusplus/ASTMatcher.cpp b/src/shared/cplusplus/ASTMatcher.cpp
index 138950c230..73decce350 100644
--- a/src/shared/cplusplus/ASTMatcher.cpp
+++ b/src/shared/cplusplus/ASTMatcher.cpp
@@ -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)
{
diff --git a/src/shared/cplusplus/ASTMatcher.h b/src/shared/cplusplus/ASTMatcher.h
index c3490ac69b..065ee66359 100644
--- a/src/shared/cplusplus/ASTMatcher.h
+++ b/src/shared/cplusplus/ASTMatcher.h
@@ -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);
diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp
index 070cf7fd85..4b08ea6375 100644
--- a/src/shared/cplusplus/ASTVisit.cpp
+++ b/src/shared/cplusplus/ASTVisit.cpp
@@ -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)) {
diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h
index d4ebdcc81a..701abd80c8 100644
--- a/src/shared/cplusplus/ASTVisitor.h
+++ b/src/shared/cplusplus/ASTVisitor.h
@@ -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 *) { }
diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h
index cefdfdc381..e38739c01e 100644
--- a/src/shared/cplusplus/ASTfwd.h
+++ b/src/shared/cplusplus/ASTfwd.h
@@ -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;
diff --git a/src/shared/cplusplus/CPlusPlusForwardDeclarations.h b/src/shared/cplusplus/CPlusPlusForwardDeclarations.h
index 836257e04f..caa90a5523 100644
--- a/src/shared/cplusplus/CPlusPlusForwardDeclarations.h
+++ b/src/shared/cplusplus/CPlusPlusForwardDeclarations.h
@@ -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
diff --git a/src/shared/cplusplus/CheckDeclaration.cpp b/src/shared/cplusplus/CheckDeclaration.cpp
index 9758f306a2..c6f747d3dd 100644
--- a/src/shared/cplusplus/CheckDeclaration.cpp
+++ b/src/shared/cplusplus/CheckDeclaration.cpp
@@ -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);
diff --git a/src/shared/cplusplus/CheckDeclaration.h b/src/shared/cplusplus/CheckDeclaration.h
index 0e11a5398b..0090a1d670 100644
--- a/src/shared/cplusplus/CheckDeclaration.h
+++ b/src/shared/cplusplus/CheckDeclaration.h
@@ -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);
diff --git a/src/shared/cplusplus/Keywords.cpp b/src/shared/cplusplus/Keywords.cpp
index 6da25125f7..51757eb8c8 100644
--- a/src/shared/cplusplus/Keywords.cpp
+++ b/src/shared/cplusplus/Keywords.cpp
@@ -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
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index b40c59c4b7..ae22e72745 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -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;
diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h
index 9fa6abb166..62e1a69418 100644
--- a/src/shared/cplusplus/Parser.h
+++ b/src/shared/cplusplus/Parser.h
@@ -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);
diff --git a/src/shared/cplusplus/Symbols.cpp b/src/shared/cplusplus/Symbols.cpp
index e19e2d123b..8b1a15e79d 100644
--- a/src/shared/cplusplus/Symbols.cpp
+++ b/src/shared/cplusplus/Symbols.cpp
@@ -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; }
diff --git a/src/shared/cplusplus/Symbols.h b/src/shared/cplusplus/Symbols.h
index 4d8d87f360..c1a1f37926 100644
--- a/src/shared/cplusplus/Symbols.h
+++ b/src/shared/cplusplus/Symbols.h
@@ -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;
diff --git a/src/shared/cplusplus/Token.cpp b/src/shared/cplusplus/Token.cpp
index ce661e43b0..61c22b7cb2 100644
--- a/src/shared/cplusplus/Token.cpp
+++ b/src/shared/cplusplus/Token.cpp
@@ -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() :
diff --git a/src/shared/cplusplus/Token.h b/src/shared/cplusplus/Token.h
index cd1cf577c6..1a24eb52b6 100644
--- a/src/shared/cplusplus/Token.h
+++ b/src/shared/cplusplus/Token.h
@@ -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,