diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h index 2117c73dcae222cbd485c9df711839d3d4c08656..a5f910e5c771f68c7ff9a5bfbe058a5d2ee90bb7 100644 --- a/src/shared/cplusplus/AST.h +++ b/src/shared/cplusplus/AST.h @@ -627,12 +627,11 @@ protected: class CPLUSPLUS_EXPORT QtFlagsDeclarationAST: public DeclarationAST { - /*Q_FLAGS(enum1 enum2 flags1 ...)*/ public: unsigned flags_specifier_token; unsigned lparen_token; + NameListAST *flag_enums_list; unsigned rparen_token; - EnumeratorListAST *enumerator_list; public: virtual QtFlagsDeclarationAST *asQtFlagsDeclaration() { return this; } @@ -649,12 +648,12 @@ protected: class CPLUSPLUS_EXPORT QtDeclareFlagsDeclarationAST: public DeclarationAST { - /*Q_DECLARE_FLAGS(flag enum)*/ public: unsigned declareflags_specifier_token; unsigned lparen_token; - unsigned flag_token; - unsigned enum_token; + SimpleNameAST *flags_name; + unsigned comma_token; + SimpleNameAST *enum_name; unsigned rparen_token; public: diff --git a/src/shared/cplusplus/ASTClone.cpp b/src/shared/cplusplus/ASTClone.cpp index 07e9217b3d3ff275db3d147799a76c390033b4ff..8fadf080ab352ff0d064f76bbf9249f05f808bb9 100644 --- a/src/shared/cplusplus/ASTClone.cpp +++ b/src/shared/cplusplus/ASTClone.cpp @@ -194,10 +194,10 @@ QtFlagsDeclarationAST *QtFlagsDeclarationAST::clone(MemoryPool *pool) const QtFlagsDeclarationAST *ast = new (pool) QtFlagsDeclarationAST; ast->flags_specifier_token = flags_specifier_token; ast->lparen_token = lparen_token; - ast->rparen_token = rparen_token; - for (EnumeratorListAST *iter = enumerator_list, **ast_iter = &ast->enumerator_list; + for (NameListAST *iter = flag_enums_list, **ast_iter = &ast->flag_enums_list; iter; iter = iter->next, ast_iter = &(*ast_iter)->next) - *ast_iter = new (pool) EnumeratorListAST((iter->value) ? iter->value->clone(pool) : 0); + *ast_iter = new (pool) NameListAST((iter->value) ? iter->value->clone(pool) : 0); + ast->rparen_token = rparen_token; return ast; } @@ -206,8 +206,11 @@ QtDeclareFlagsDeclarationAST *QtDeclareFlagsDeclarationAST::clone(MemoryPool *po QtDeclareFlagsDeclarationAST *ast = new (pool) QtDeclareFlagsDeclarationAST; ast->declareflags_specifier_token = declareflags_specifier_token; ast->lparen_token = lparen_token; - ast->flag_token = flag_token; - ast->enum_token = enum_token; + if (flags_name) + ast->flags_name = flags_name->clone(pool); + ast->comma_token = comma_token; + if (enum_name) + ast->enum_name = enum_name->clone(pool); ast->rparen_token = rparen_token; return ast; } diff --git a/src/shared/cplusplus/ASTMatcher.cpp b/src/shared/cplusplus/ASTMatcher.cpp index 25b0ef3d2d531969fb06152d21a2f761e9568f2d..75ff5eceb8c997c38e49739b22b14473ec41a703 100644 --- a/src/shared/cplusplus/ASTMatcher.cpp +++ b/src/shared/cplusplus/ASTMatcher.cpp @@ -318,13 +318,13 @@ bool ASTMatcher::match(QtFlagsDeclarationAST *node, QtFlagsDeclarationAST *patte pattern->lparen_token = node->lparen_token; - pattern->rparen_token = node->rparen_token; - - if (! pattern->enumerator_list) - pattern->enumerator_list = node->enumerator_list; - else if (! AST::match(node->enumerator_list, pattern->enumerator_list, this)) + if (! pattern->flag_enums_list) + pattern->flag_enums_list = node->flag_enums_list; + else if (! AST::match(node->flag_enums_list, pattern->flag_enums_list, this)) return false; + pattern->rparen_token = node->rparen_token; + return true; } @@ -337,9 +337,17 @@ bool ASTMatcher::match(QtDeclareFlagsDeclarationAST *node, QtDeclareFlagsDeclara pattern->lparen_token = node->lparen_token; - pattern->flag_token = node->flag_token; + if (! pattern->flags_name) + pattern->flags_name = node->flags_name; + else if (! AST::match(node->flags_name, pattern->flags_name, this)) + return false; - pattern->enum_token = node->enum_token; + pattern->comma_token = node->comma_token; + + if (! pattern->enum_name) + pattern->enum_name = node->enum_name; + else if (! AST::match(node->enum_name, pattern->enum_name, this)) + return false; pattern->rparen_token = node->rparen_token; diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp index 68e1d7219fd0fc014b692b0388d642ecdbf954ef..e37c96493959a3bbd107ffe0dd2b7693a3142e84 100644 --- a/src/shared/cplusplus/ASTVisit.cpp +++ b/src/shared/cplusplus/ASTVisit.cpp @@ -136,7 +136,7 @@ void QtEnumDeclarationAST::accept0(ASTVisitor *visitor) void QtFlagsDeclarationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - accept(enumerator_list, visitor); + accept(flag_enums_list, visitor); } visitor->endVisit(this); } @@ -144,6 +144,8 @@ void QtFlagsDeclarationAST::accept0(ASTVisitor *visitor) void QtDeclareFlagsDeclarationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { + accept(flags_name, visitor); + accept(enum_name, visitor); } visitor->endVisit(this); } diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp index 072cecc1037ca844ac136f21d5800a2ff457a496..33f7660129b5ebd07d6339b507a8a889cb949188 100644 --- a/src/shared/cplusplus/Parser.cpp +++ b/src/shared/cplusplus/Parser.cpp @@ -1781,7 +1781,7 @@ bool Parser::parseAccessDeclaration(DeclarationAST *&node) parenthesis is that the type is the first parameter and the name comes after the type. */ -bool Parser::parseQPropertyDeclaration(DeclarationAST *&node) +bool Parser::parseQtPropertyDeclaration(DeclarationAST *&node) { DEBUG_THIS_RULE(); if (LA() != T_Q_PROPERTY) @@ -1895,7 +1895,7 @@ bool Parser::matchBoolean(BoolLiteralAST *&node) // so, these are not allowed: // Q_ENUMS // Q_ENUMS(Priority, Severity) -bool Parser::parseQEnumDeclaration(DeclarationAST *&node) +bool Parser::parseQtEnumDeclaration(DeclarationAST *&node) { DEBUG_THIS_RULE(); if (LA() != T_Q_ENUMS) @@ -1915,60 +1915,59 @@ bool Parser::parseQEnumDeclaration(DeclarationAST *&node) return true; } -#ifdef ICHECK_BUILD -bool Parser::parseQFlags(DeclarationAST *&node) +// q-flags-decl ::= 'Q_FLAGS' '(' q-flags-list? ')' +// q-flags-list ::= identifier +// q-flags-list ::= q-flags-list identifier +// +// Note: Q_FLAGS is a CPP macro with exactly 1 parameter. +// Examples of valid uses: +// Q_FLAGS() +// Q_FLAGS(Orientation) +// Q_FLAGS(Orientation DropActions) +// so, these are not allowed: +// Q_FLAGS +// Q_FLAGS(Orientation, DropActions) +bool Parser::parseQtFlags(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; + if (LA() != T_Q_FLAGS) + return false; + + QtFlagsDeclarationAST *ast = new (_pool) QtFlagsDeclarationAST; + ast->flags_specifier_token = consumeToken(); + match(T_LPAREN, &ast->lparen_token); + for (NameListAST **iter = &ast->flag_enums_list; LA() == T_IDENTIFIER; iter = &(*iter)->next) { + *iter = new (_pool) NameListAST; + SimpleNameAST *name = new (_pool) SimpleNameAST; + name->identifier_token = consumeToken(); + (*iter)->value = name; } - return false; + match(T_RPAREN, &ast->rparen_token); + node = ast; + return true; } -bool Parser::parseQDeclareFlags(DeclarationAST *&node) +// q-declare-flags ::= 'Q_DECLARE_FLAGS' '(' q-flags-name ',' q-enum-name ')' +// q-flags-name ::= T_IDENTIFIER +// q-enum-name ::= T_IDENTIFIER +bool Parser::parseQtDeclareFlags(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; + if (LA() != T_Q_DECLARE_FLAGS) + return false; + + QtDeclareFlagsDeclarationAST *ast = new (_pool) QtDeclareFlagsDeclarationAST; + ast->declareflags_specifier_token = consumeToken(); + match(T_LPAREN, &ast->lparen_token); + ast->flags_name = new (_pool) SimpleNameAST; + match(T_IDENTIFIER, &ast->flags_name->identifier_token); + match(T_COMMA, &ast->comma_token); + match(T_IDENTIFIER, &ast->enum_name->identifier_token); + match(T_RPAREN, &ast->rparen_token); + node = ast; + return true; } -#endif bool Parser::parseMemberSpecification(DeclarationAST *&node) { @@ -1991,10 +1990,10 @@ bool Parser::parseMemberSpecification(DeclarationAST *&node) return parseAccessDeclaration(node); case T_Q_PROPERTY: - return parseQPropertyDeclaration(node); + return parseQtPropertyDeclaration(node); case T_Q_ENUMS: - return parseQEnumDeclaration(node); + return parseQtEnumDeclaration(node); #ifdef ICHECK_BUILD case T_Q_FLAGS: diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h index ae4f338a6f324d3ec68f564528158d66cad4efc5..dddf081dd918371d27a25ddc648232f5d05e8060 100644 --- a/src/shared/cplusplus/Parser.h +++ b/src/shared/cplusplus/Parser.h @@ -78,13 +78,11 @@ public: bool parseAbstractDeclarator(DeclaratorAST *&node); bool parseEmptyDeclaration(DeclarationAST *&node); bool parseAccessDeclaration(DeclarationAST *&node); - bool parseQPropertyDeclaration(DeclarationAST *&node); + bool parseQtPropertyDeclaration(DeclarationAST *&node); bool matchBoolean(BoolLiteralAST *&node); - bool parseQEnumDeclaration(DeclarationAST *&node); -#ifdef ICHECK_BUILD - bool parseQFlags(DeclarationAST *&node); - bool parseQDeclareFlags(DeclarationAST *&node); -#endif + bool parseQtEnumDeclaration(DeclarationAST *&node); + bool parseQtFlags(DeclarationAST *&node); + bool parseQtDeclareFlags(DeclarationAST *&node); bool parseAdditiveExpression(ExpressionAST *&node); bool parseAndExpression(ExpressionAST *&node); bool parseAsmDefinition(DeclarationAST *&node);