diff options
author | Wolfgang Beck <wolfgang.beck@nokia.com> | 2010-01-19 15:26:08 +1000 |
---|---|---|
committer | Wolfgang Beck <wolfgang.beck@nokia.com> | 2010-01-19 15:26:08 +1000 |
commit | 4b3388172904e629fc6f6f1e3a6323e8fe12b97f (patch) | |
tree | 098dca6bbe72201050a4d8ec94c008903eb67ed3 /src/shared/cplusplus | |
parent | 29b7594b38f3545bb6a5d5ff08542c0e71a30197 (diff) | |
download | qt-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.cpp | 45 | ||||
-rw-r--r-- | src/shared/cplusplus/AST.h | 112 | ||||
-rw-r--r-- | src/shared/cplusplus/ASTMatch0.cpp | 34 | ||||
-rw-r--r-- | src/shared/cplusplus/ASTMatcher.cpp | 66 | ||||
-rw-r--r-- | src/shared/cplusplus/ASTMatcher.h | 6 | ||||
-rw-r--r-- | src/shared/cplusplus/ASTVisit.cpp | 30 | ||||
-rw-r--r-- | src/shared/cplusplus/ASTVisitor.h | 12 | ||||
-rw-r--r-- | src/shared/cplusplus/ASTfwd.h | 6 | ||||
-rw-r--r-- | src/shared/cplusplus/CPlusPlusForwardDeclarations.h | 6 | ||||
-rw-r--r-- | src/shared/cplusplus/CheckDeclaration.cpp | 36 | ||||
-rw-r--r-- | src/shared/cplusplus/CheckDeclaration.h | 6 | ||||
-rw-r--r-- | src/shared/cplusplus/Keywords.cpp | 112 | ||||
-rw-r--r-- | src/shared/cplusplus/Parser.cpp | 183 | ||||
-rw-r--r-- | src/shared/cplusplus/Parser.h | 6 | ||||
-rw-r--r-- | src/shared/cplusplus/Symbols.cpp | 43 | ||||
-rw-r--r-- | src/shared/cplusplus/Symbols.h | 11 | ||||
-rw-r--r-- | src/shared/cplusplus/Token.cpp | 6 | ||||
-rw-r--r-- | src/shared/cplusplus/Token.h | 11 |
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, |