summaryrefslogtreecommitdiff
path: root/src/shared/cplusplus/Parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared/cplusplus/Parser.cpp')
-rw-r--r--src/shared/cplusplus/Parser.cpp260
1 files changed, 162 insertions, 98 deletions
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index 864ec779ab..072cecc103 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -53,10 +53,8 @@
#include "AST.h"
#include "Literals.h"
#include "ObjectiveCTypeQualifiers.h"
+#include "QtContextKeywords.h"
#include <cstdio> // for putchar
-#ifdef ICHECK_BUILD
-# include <QString>
-#endif
#define CPLUSPLUS_NO_DEBUG_RULE
#define MAX_EXPRESSION_DEPTH 100
@@ -1762,107 +1760,165 @@ bool Parser::parseAccessDeclaration(DeclarationAST *&node)
return false;
}
-#ifdef ICHECK_BUILD
+/*
+ Q_PROPERTY(type name
+ READ getFunction
+ [WRITE setFunction]
+ [RESET resetFunction]
+ [NOTIFY notifySignal]
+ [DESIGNABLE bool]
+ [SCRIPTABLE bool]
+ [STORED bool]
+ [USER bool]
+ [CONSTANT]
+ [FINAL])
+
+ Note that "type" appears to be any valid type. So these are valid:
+ Q_PROPERTY(const char *zoo READ zoo)
+ Q_PROPERTY(const class Blah *blah READ blah)
+
+ Furthermore, the only restriction on the order of the items in between the
+ parenthesis is that the type is the first parameter and the name comes after
+ the type.
+*/
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();
+ DEBUG_THIS_RULE();
+ if (LA() != T_Q_PROPERTY)
+ return false;
+
+ QtPropertyDeclarationAST *ast = new (_pool)QtPropertyDeclarationAST;
+ ast->property_specifier_token = consumeToken();
+ if (LA() == T_LPAREN) {
+ ast->lparen_token = consumeToken();
+ parseTypeId(ast->type_id);
+ ast->type_name = new (_pool) SimpleNameAST;
+ match(T_IDENTIFIER, &ast->type_name->identifier_token);
+
+ while (true) {
+ if (LA() == T_RPAREN) {
+ ast->rparen_token = consumeToken();
+ node = ast;
+ break;
+ } else if (LA() == T_IDENTIFIER) {
+ switch (peekAtQtContextKeyword()) {
+ case Token_READ:
+ ast->read_token = consumeToken();
+ ast->read_function = new (_pool) SimpleNameAST;
+ match(T_IDENTIFIER, &ast->read_function->identifier_token);
+ break;
+
+ case Token_WRITE:
+ ast->write_token = consumeToken();
+ ast->write_function = new (_pool) SimpleNameAST;
+ match(T_IDENTIFIER, &ast->write_function->identifier_token);
+ break;
+
+ case Token_RESET:
+ ast->reset_token = consumeToken();
+ ast->reset_function = new (_pool) SimpleNameAST;
+ match(T_IDENTIFIER, &ast->reset_function->identifier_token);
+ break;
+
+ case Token_NOTIFY:
+ ast->notify_token = consumeToken();
+ ast->notify_function = new (_pool) SimpleNameAST;
+ match(T_IDENTIFIER, &ast->notify_function->identifier_token);
+ break;
+
+ case Token_DESIGNABLE:
+ ast->designable_token = consumeToken();
+ if (!matchBoolean(ast->designable_value))
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;
- }
+ break;
+
+ case Token_SCRIPTABLE:
+ ast->scriptable_token = consumeToken();
+ if (!matchBoolean(ast->scriptable_value))
+ break;
+ break;
+
+ case Token_STORED:
+ ast->stored_token = consumeToken();
+ if (!matchBoolean(ast->stored_value))
+ break;
+ break;
+
+ case Token_USER:
+ ast->user_token = consumeToken();
+ if (!matchBoolean(ast->user_value))
+ break;
+ break;
+
+ case Token_CONSTANT:
+ ast->constant_token = consumeToken();
+ break;
+
+ case Token_FINAL:
+ ast->final_token = consumeToken();
+ break;
+
+ default:
+ _translationUnit->error(cursor(), "expected `)' before `%s'", tok().spell());
+ return true;
}
+ } else {
+ _translationUnit->error(cursor(), "expected `)' before `%s'", tok().spell());
+ break;
}
}
- node = ast;
+ }
+ return true;
+}
+
+bool Parser::matchBoolean(BoolLiteralAST *&node)
+{
+ ExpressionAST *expr = 0;
+ if (parseBoolLiteral(expr)) {
+ node = expr->asBoolLiteral();
return true;
+ } else {
+ _translationUnit->error(cursor(), "expected `true' or `false' before `%s'", tok().spell());
+ return false;
}
- return false;
}
+// q-enums-decl ::= 'Q_ENUMS' '(' q-enums-list? ')'
+// q-enums-list ::= identifier
+// q-enums-list ::= q-enums-list identifier
+//
+// Note: Q_ENUMS is a CPP macro with exactly 1 parameter.
+// Examples of valid uses:
+// Q_ENUMS()
+// Q_ENUMS(Priority)
+// Q_ENUMS(Priority Severity)
+// so, these are not allowed:
+// Q_ENUMS
+// Q_ENUMS(Priority, Severity)
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_Q_ENUMS)
+ return false;
- 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;
+ QtEnumDeclarationAST *ast = new (_pool) QtEnumDeclarationAST;
+ ast->enum_specifier_token = consumeToken();
+ match(T_LPAREN, &ast->lparen_token);
+ for (NameListAST **iter = &ast->enumerator_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;
}
+#ifdef ICHECK_BUILD
bool Parser::parseQFlags(DeclarationAST *&node)
{
- /*Q_FLAGS(enum1 enum2 flags1)*/
+ /*Q_FLAGS(enum1 enum2 flags1)*/
DEBUG_THIS_RULE();
if (LA() == T_Q_FLAGS) {
QFlagsDeclarationAST *ast = new (_pool)QFlagsDeclarationAST;
@@ -1934,13 +1990,13 @@ bool Parser::parseMemberSpecification(DeclarationAST *&node)
case T_Q_SLOTS:
return parseAccessDeclaration(node);
-#ifdef ICHECK_BUILD
case T_Q_PROPERTY:
return parseQPropertyDeclaration(node);
case T_Q_ENUMS:
return parseQEnumDeclaration(node);
+#ifdef ICHECK_BUILD
case T_Q_FLAGS:
return parseQFlags(node);
@@ -4496,17 +4552,17 @@ bool Parser::parseObjCClassForwardDeclaration(DeclarationAST *&node)
unsigned identifier_token = 0;
match(T_IDENTIFIER, &identifier_token);
- ast->identifier_list = new (_pool) ObjCIdentifierListAST;
+ ast->identifier_list = new (_pool) NameListAST;
SimpleNameAST *name = new (_pool) SimpleNameAST;
name->identifier_token = identifier_token;
ast->identifier_list->value = name;
- ObjCIdentifierListAST **nextId = &ast->identifier_list->next;
+ NameListAST **nextId = &ast->identifier_list->next;
while (LA() == T_COMMA) {
consumeToken(); // consume T_COMMA
match(T_IDENTIFIER, &identifier_token);
- *nextId = new (_pool) ObjCIdentifierListAST;
+ *nextId = new (_pool) NameListAST;
name = new (_pool) SimpleNameAST;
name->identifier_token = identifier_token;
(*nextId)->value = name;
@@ -4646,17 +4702,17 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node,
ObjCProtocolForwardDeclarationAST *ast = new (_pool) ObjCProtocolForwardDeclarationAST;
ast->attribute_list = attributes;
ast->protocol_token = protocol_token;
- ast->identifier_list = new (_pool) ObjCIdentifierListAST;
+ ast->identifier_list = new (_pool) NameListAST;
SimpleNameAST *name = new (_pool) SimpleNameAST;
name->identifier_token = identifier_token;
ast->identifier_list->value = name;
- ObjCIdentifierListAST **nextId = &ast->identifier_list->next;
+ NameListAST **nextId = &ast->identifier_list->next;
while (LA() == T_COMMA) {
consumeToken(); // consume T_COMMA
match(T_IDENTIFIER, &identifier_token);
- *nextId = new (_pool) ObjCIdentifierListAST;
+ *nextId = new (_pool) NameListAST;
name = new (_pool) SimpleNameAST;
name->identifier_token = identifier_token;
(*nextId)->value = name;
@@ -4810,16 +4866,16 @@ bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node)
case T_AT_DYNAMIC: {
ObjCDynamicPropertiesDeclarationAST *ast = new (_pool) ObjCDynamicPropertiesDeclarationAST;
ast->dynamic_token = consumeToken();
- ast->property_identifier_list = new (_pool) ObjCIdentifierListAST;
+ ast->property_identifier_list = new (_pool) NameListAST;
SimpleNameAST *name = new (_pool) SimpleNameAST;
match(T_IDENTIFIER, &name->identifier_token);
ast->property_identifier_list->value = name;
- ObjCIdentifierListAST *last = ast->property_identifier_list;
+ NameListAST *last = ast->property_identifier_list;
while (LA() == T_COMMA) {
consumeToken(); // consume T_COMMA
- last->next = new (_pool) ObjCIdentifierListAST;
+ last->next = new (_pool) NameListAST;
last = last->next;
name = new (_pool) SimpleNameAST;
match(T_IDENTIFIER, &name->identifier_token);
@@ -4895,17 +4951,17 @@ bool Parser::parseObjCProtocolRefs(ObjCProtocolRefsAST *&node)
unsigned identifier_token = 0;
match(T_IDENTIFIER, &identifier_token);
- ast->identifier_list = new (_pool) ObjCIdentifierListAST;
+ ast->identifier_list = new (_pool) NameListAST;
SimpleNameAST *name = new (_pool) SimpleNameAST;
name->identifier_token = identifier_token;
ast->identifier_list->value = name;
- ObjCIdentifierListAST **nextId = &ast->identifier_list->next;
+ NameListAST **nextId = &ast->identifier_list->next;
while (LA() == T_COMMA) {
consumeToken(); // consume T_COMMA
match(T_IDENTIFIER, &identifier_token);
- *nextId = new (_pool) ObjCIdentifierListAST;
+ *nextId = new (_pool) NameListAST;
name = new (_pool) SimpleNameAST;
name->identifier_token = identifier_token;
(*nextId)->value = name;
@@ -5289,4 +5345,12 @@ bool Parser::parseObjCContextKeyword(int kind, unsigned &in_token)
return true;
}
+int Parser::peekAtQtContextKeyword() const
+{
+ DEBUG_THIS_RULE();
+ if (LA() != T_IDENTIFIER)
+ return false;
+ const Identifier *id = tok().identifier;
+ return classifyQtContextKeyword(id->chars(), id->size());
+}