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);