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