From 61132f260c029c868e1971771424c62f36cef638 Mon Sep 17 00:00:00 2001
From: Erik Verbruggen <erik.verbruggen@nokia.com>
Date: Tue, 16 Mar 2010 16:38:02 +0100
Subject: [PATCH] Fixed Q_ENUMS/Q_FLAGS parsing of enum names.

---
 src/shared/cplusplus/CheckDeclaration.cpp | 41 ++++++++++++++++++++---
 src/shared/cplusplus/CheckDeclaration.h   |  3 ++
 src/shared/cplusplus/Parser.cpp           | 35 ++-----------------
 src/shared/cplusplus/Parser.h             |  1 -
 4 files changed, 42 insertions(+), 38 deletions(-)

diff --git a/src/shared/cplusplus/CheckDeclaration.cpp b/src/shared/cplusplus/CheckDeclaration.cpp
index efd87f7cc08..828ec6d381e 100644
--- a/src/shared/cplusplus/CheckDeclaration.cpp
+++ b/src/shared/cplusplus/CheckDeclaration.cpp
@@ -805,15 +805,13 @@ bool CheckDeclaration::visit(ObjCPropertyDeclarationAST *ast)
 
 bool CheckDeclaration::visit(QtEnumDeclarationAST *ast)
 {
-    for (NameListAST *iter = ast->enumerator_list; iter; iter = iter->next)
-        semantic()->check(iter->value, _scope);
+    checkQEnumsQFlagsNames(ast->enumerator_list, "Q_ENUMS");
     return false;
 }
 
 bool CheckDeclaration::visit(QtFlagsDeclarationAST *ast)
 {
-    for (NameListAST *iter = ast->flag_enums_list; iter; iter = iter->next)
-        semantic()->check(iter->value, _scope);
+    checkQEnumsQFlagsNames(ast->flag_enums_list, "Q_FLAGS");
     return false;
 }
 
@@ -830,3 +828,38 @@ bool CheckDeclaration::visit(QtPropertyDeclarationAST *ast)
     }
     return false;
 }
+
+void CheckDeclaration::checkQEnumsQFlagsNames(NameListAST *nameListAst,
+                                              const char *declName)
+{
+    for (NameListAST *iter = nameListAst; iter; iter = iter->next) {
+        if (!iter)
+            continue;
+
+        const Name *name = semantic()->check(iter->value, _scope);
+        if (!name)
+            continue;
+
+        if (name->isNameId())
+            continue;
+
+        const QualifiedNameId *qName = name->asQualifiedNameId();
+        if (!qName)
+            translationUnit()->error(iter->firstToken(), "invalid name in %s",
+                                     declName);
+        else if (qName->isGlobal())
+                translationUnit()->error(iter->firstToken(),
+                                         "invalid name '%s' in %s",
+                                         qName->identifier()->chars(), declName);
+        else {
+            for (unsigned i = 0; i < qName->nameCount(); ++i) {
+                const Name *namePart = qName->nameAt(i);
+                if (!namePart || !namePart->isNameId()) {
+                    translationUnit()->error(iter->firstToken(),
+                                             "invalid name '%s' in %s",
+                                             qName->identifier()->chars(), declName);
+                }
+            }
+        }
+    }
+}
diff --git a/src/shared/cplusplus/CheckDeclaration.h b/src/shared/cplusplus/CheckDeclaration.h
index f82cdb25126..d2977a51f0a 100644
--- a/src/shared/cplusplus/CheckDeclaration.h
+++ b/src/shared/cplusplus/CheckDeclaration.h
@@ -107,6 +107,9 @@ private:
     bool checkPropertyAttribute(ObjCPropertyAttributeAST *attrAst,
                                 int &flags,
                                 int attr);
+    void checkQEnumsQFlagsNames(NameListAST *nameListAst,
+                                const char *declName);
+
 private:
     DeclarationAST *_declaration;
     Scope *_scope;
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index 494f477ec81..93b30251c7c 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -1899,7 +1899,7 @@ bool Parser::parseQtEnumDeclaration(DeclarationAST *&node)
     match(T_LPAREN, &ast->lparen_token);
     for (NameListAST **iter = &ast->enumerator_list; LA() && LA() != T_RPAREN; iter = &(*iter)->next) {
         NameAST *name_ast = 0;
-        if (!parseEnumName(name_ast))
+        if (!parseName(name_ast))
             break;
         *iter = new (_pool) NameListAST;
         (*iter)->value = name_ast;
@@ -1909,37 +1909,6 @@ bool Parser::parseQtEnumDeclaration(DeclarationAST *&node)
     return true;
 }
 
-bool Parser::parseEnumName(NameAST *&node)
-{
-    DEBUG_THIS_RULE();
-
-    unsigned global_scope_token = 0;
-    if (LA() == T_COLON_COLON)
-        global_scope_token = consumeToken();
-
-    NestedNameSpecifierListAST *nested_name_specifier = 0;
-    parseNestedNameSpecifierOpt(nested_name_specifier,
-                                /*acceptTemplateId=*/ true);
-
-    unsigned identifier_token = 0;
-    match(T_IDENTIFIER, &identifier_token);
-    if (global_scope_token == 0 && nested_name_specifier == 0
-        && identifier_token == 0)
-        return false;
-
-    SimpleNameAST *name_ast = new (_pool) SimpleNameAST;
-    name_ast->identifier_token = identifier_token;
-    if (nested_name_specifier || global_scope_token) {
-        QualifiedNameAST *q_name_ast = new (_pool) QualifiedNameAST;
-        q_name_ast->nested_name_specifier_list = nested_name_specifier;
-        q_name_ast->unqualified_name = name_ast;
-        q_name_ast->global_scope_token = global_scope_token;
-    } else {
-        node = name_ast;
-    }
-    return true;
-}
-
 // q-flags-decl ::= 'Q_FLAGS' '(' q-flags-list? ')'
 // q-flags-list ::= identifier
 // q-flags-list ::= q-flags-list identifier
@@ -1963,7 +1932,7 @@ bool Parser::parseQtFlags(DeclarationAST *&node)
     match(T_LPAREN, &ast->lparen_token);
     for (NameListAST **iter = &ast->flag_enums_list; LA() && LA() != T_RPAREN; iter = &(*iter)->next) {
         NameAST *name_ast = 0;
-        if (!parseEnumName(name_ast))
+        if (!parseName(name_ast))
             break;
         *iter = new (_pool) NameListAST;
         (*iter)->value = name_ast;
diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h
index 0f62c38b872..e10be3ac81d 100644
--- a/src/shared/cplusplus/Parser.h
+++ b/src/shared/cplusplus/Parser.h
@@ -80,7 +80,6 @@ public:
     bool parseAccessDeclaration(DeclarationAST *&node);
     bool parseQtPropertyDeclaration(DeclarationAST *&node);
     bool parseQtEnumDeclaration(DeclarationAST *&node);
-    bool parseEnumName(NameAST *&node);
     bool parseQtFlags(DeclarationAST *&node);
     bool parseAdditiveExpression(ExpressionAST *&node);
     bool parseAndExpression(ExpressionAST *&node);
-- 
GitLab