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.cpp148
1 files changed, 95 insertions, 53 deletions
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index b75c10d9dd..2856e07622 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -63,6 +63,7 @@ Parser::Parser(TranslationUnit *unit)
: _translationUnit(unit),
_control(_translationUnit->control()),
_pool(_translationUnit->memoryPool()),
+ _objcInContextKeyword(_control->findOrInsertIdentifier("in")),
_tokenIndex(1),
_templateArguments(0),
_qtMocRunEnabled(false),
@@ -422,7 +423,10 @@ bool Parser::parseDeclaration(DeclarationAST *&node)
return parseObjCImplementation(node);
case T_AT_END:
- return parseObjCEnd(node);
+ // TODO: should this be done here, or higher-up?
+ _translationUnit->error(cursor(), "skip stray token `%s'", tok().spell());
+ consumeToken();
+ break;
default: {
if (_objCEnabled && LA() == T___ATTRIBUTE__) {
@@ -2168,20 +2172,43 @@ bool Parser::parseForeachStatement(StatementAST *&node)
bool Parser::parseForStatement(StatementAST *&node)
{
- if (LA() == T_FOR) {
+ if (LA() != T_FOR)
+ return false;
+
+ unsigned for_token = consumeToken();
+ unsigned lparen_token = 0;
+ match(T_LPAREN, &lparen_token);
+ StatementAST *initializer = 0;
+ parseForInitStatement(initializer);
+
+ if (LA() == T_IDENTIFIER && tok().identifier == _objcInContextKeyword) {
+ ObjCFastEnumerationAST *ast = new (_pool) ObjCFastEnumerationAST;
+
+ ast->for_token = for_token;
+ ast->lparen_token = lparen_token;
+ ast->initializer = initializer;
+ ast->in_token = consumeToken();
+ parseExpression(ast->fast_enumeratable_expression);
+ match(T_RPAREN, &ast->rparen_token);
+ parseStatement(ast->body_statement);
+
+ node = ast;
+ } else {
ForStatementAST *ast = new (_pool) ForStatementAST;
- ast->for_token = consumeToken();
- match(T_LPAREN, &ast->lparen_token);
- parseForInitStatement(ast->initializer);
+
+ ast->for_token = for_token;
+ ast->lparen_token = lparen_token;
+ ast->initializer = initializer;
parseExpression(ast->condition);
match(T_SEMICOLON, &ast->semicolon_token);
parseExpression(ast->expression);
match(T_RPAREN, &ast->rparen_token);
parseStatement(ast->statement);
+
node = ast;
- return true;
}
- return false;
+
+ return true;
}
bool Parser::parseForInitStatement(StatementAST *&node)
@@ -3951,7 +3978,7 @@ bool Parser::parseObjCInterface(DeclarationAST *&node,
"invalid attributes for category interface declaration");
ObjCCategoryInterfaceDeclarationAST *ast = new (_pool) ObjCCategoryInterfaceDeclarationAST;
- // XXX: Should the attributes get stored anyway? (for fixing/refactoring purposes maybe...)
+ // TODO: Should the attributes get stored anyway? (for fixing/refactoring purposes maybe...)
ast->interface_token = objc_interface_token;
ast->class_identifier_token = identifier_token;
@@ -4074,48 +4101,62 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node,
// objc-class-instance-variables-opt
// objc-implementation ::= T_AT_IMPLEMENTAION T_IDENTIFIER T_LPAREN T_IDENTIFIER T_RPAREN
//
-bool Parser::parseObjCImplementation(DeclarationAST *&)
+bool Parser::parseObjCImplementation(DeclarationAST *&node)
{
if (LA() != T_AT_IMPLEMENTATION)
return false;
- consumeToken();
-
+ unsigned implementation_token = consumeToken();
unsigned identifier_token = 0;
match(T_IDENTIFIER, &identifier_token);
if (LA() == T_LPAREN) {
// a category implementation
- unsigned lparen_token = 0, rparen_token = 0;
- unsigned category_name_token = 0;
- match(T_LPAREN, &lparen_token);
- match(T_IDENTIFIER, &category_name_token);
- match(T_RPAREN, &rparen_token);
- return true;
- }
+ ObjCCategoryImplementationAST *ast = new (_pool) ObjCCategoryImplementationAST;
+ ast->implementation_token = implementation_token;
+ ast->class_identifier = identifier_token;
- // a class implementation
- if (LA() == T_COLON) {
- consumeToken();
- unsigned super_class_name_token = 0;
- match(T_IDENTIFIER, &super_class_name_token);
+ match(T_LPAREN, &(ast->lparen_token));
+ match(T_IDENTIFIER, &(ast->category_name_token));
+ match(T_RPAREN, &(ast->rparen_token));
+
+ parseObjCMethodDefinitionList(ast->declarations);
+ match(T_AT_END, &(ast->end_token));
+
+ node = ast;
+ } else {
+ // a class implementation
+ ObjCClassImplementationAST *ast = new (_pool) ObjCClassImplementationAST;
+ ast->implementation_token = implementation_token;
+ ast->class_identifier = identifier_token;
+
+ if (LA() == T_COLON) {
+ ast->colon_token = consumeToken();
+ match(T_IDENTIFIER, &(ast->super_class_identifier));
+ }
+
+ parseObjClassInstanceVariables(ast->inst_vars_decl);
+ parseObjCMethodDefinitionList(ast->declarations);
+ match(T_AT_END, &(ast->end_token));
+
+ node = ast;
}
- ObjCInstanceVariablesDeclarationAST *inst_vars_decl;
- parseObjClassInstanceVariables(inst_vars_decl);
- parseObjCMethodDefinitionList();
return true;
}
-bool Parser::parseObjCMethodDefinitionList()
+bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node)
{
+ DeclarationListAST **next = &node;
+
while (LA() && LA() != T_AT_END) {
unsigned start = cursor();
+ DeclarationAST *declaration = 0;
switch (LA()) {
case T_PLUS:
case T_MINUS:
- parseObjCMethodDefinition();
+ parseObjCMethodDefinition(declaration);
if (start == cursor())
consumeToken();
@@ -4126,7 +4167,9 @@ bool Parser::parseObjCMethodDefinitionList()
break;
case T_AT_SYNTHESIZE: {
- consumeToken();
+ ObjCSynthesizedPropertiesDeclarationAST *ast = new (_pool) ObjCSynthesizedPropertiesDeclarationAST;
+ ast->synthesized_token = consumeToken();
+ // TODO EV
unsigned identifier_token = 0;
match(T_IDENTIFIER, &identifier_token);
@@ -4150,34 +4193,36 @@ bool Parser::parseObjCMethodDefinitionList()
}
}
- unsigned semicolon_token = 0;
- match(T_SEMICOLON, &semicolon_token);
+ match(T_SEMICOLON, &(ast->semicolon_token));
+ declaration = ast;
break;
}
case T_AT_DYNAMIC: {
- consumeToken();
- unsigned identifier_token = 0;
- match(T_IDENTIFIER, &identifier_token);
+ ObjCDynamicPropertiesDeclarationAST *ast = new (_pool) ObjCDynamicPropertiesDeclarationAST;
+ ast->dynamic_token = consumeToken();
+ ast->property_identifiers = new (_pool) IdentifierListAST;
+ match(T_IDENTIFIER, &(ast->property_identifiers->identifier_token));
+ IdentifierListAST *last = ast->property_identifiers;
while (LA() == T_COMMA) {
- consumeToken();
- match(T_IDENTIFIER, &identifier_token);
+ last->comma_token = consumeToken();
+ last->next = new (_pool) IdentifierListAST;
+ last = last->next;
+ match(T_IDENTIFIER, &(last->identifier_token));
}
- unsigned semicolon_token = 0;
- match(T_SEMICOLON, &semicolon_token);
+ match(T_SEMICOLON, &(ast->semicolon_token));
+ declaration = ast;
break;
}
default:
if (LA() == T_EXTERN && LA(2) == T_STRING_LITERAL) {
- DeclarationAST *declaration = 0;
parseDeclaration(declaration);
} else {
- DeclarationAST *declaration = 0;
if (! parseBlockDeclaration(declaration)) {
rewind(start);
_translationUnit->error(cursor(),
@@ -4188,13 +4233,20 @@ bool Parser::parseObjCMethodDefinitionList()
}
break;
} // switch
+
+ if (declaration) {
+ *next = new (_pool) DeclarationListAST;
+ (*next)->declaration = declaration;
+ next = &((*next)->next);
+ }
}
return true;
}
-bool Parser::parseObjCMethodDefinition()
+bool Parser::parseObjCMethodDefinition(DeclarationAST *&node)
{
+ // TODO EV:
DeclarationAST *ast = 0;
if (! parseObjCMethodPrototype(ast))
return false;
@@ -4339,12 +4391,13 @@ bool Parser::parseObjCInstanceVariableDeclaration(DeclarationAST *&node)
// objc-property-declaration ::=
// T_AT_PROPERTY T_LPAREN (property-attribute @ T_COMMA) T_RPAREN simple-declaration
//
-bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&node, SpecifierAST *)
+bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&node, SpecifierAST *attributes)
{
if (LA() != T_AT_PROPERTY)
return false;
ObjCPropertyDeclarationAST *ast = new (_pool) ObjCPropertyDeclarationAST;
+ ast->attributes = attributes;
ast->property_token = consumeToken();
if (LA() == T_LPAREN) {
@@ -4518,15 +4571,4 @@ bool Parser::parseObjCTypeQualifiers(unsigned &type_qualifier)
return true;
}
-// objc-end: T_AT_END
-bool Parser::parseObjCEnd(DeclarationAST *&)
-{
- if (LA() != T_AT_END)
- return false;
-
- consumeToken();
- return true;
-}
-
-
CPLUSPLUS_END_NAMESPACE