forked from qt-creator/qt-creator
Revert "Split Objective-C keyword parsing to handle the '@' separately."
This reverts commit 2a59d2ae0c
.
This commit is contained in:
@@ -293,22 +293,13 @@ void Parser::skipUntilDeclaration()
|
||||
case T_NAMESPACE:
|
||||
case T_ASM:
|
||||
case T_EXPORT:
|
||||
case T_AT_CLASS:
|
||||
case T_AT_INTERFACE:
|
||||
case T_AT_PROTOCOL:
|
||||
case T_AT_IMPLEMENTATION:
|
||||
case T_AT_END:
|
||||
return;
|
||||
|
||||
// ObjC declarations:
|
||||
case T_AT:
|
||||
switch (LA(2)) {
|
||||
case T_CLASS:
|
||||
case T_INTERFACE:
|
||||
case T_PROTOCOL:
|
||||
case T_IMPLEMENTATION:
|
||||
case T_END:
|
||||
return;
|
||||
default: {
|
||||
// INTENTIONAL FALL-THROUGH!
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
if (lookAtBuiltinTypeSpecifier() || lookAtClassKey() ||
|
||||
lookAtFunctionSpecifier() || lookAtStorageClassSpecifier())
|
||||
@@ -361,8 +352,8 @@ bool Parser::skipUntilStatement()
|
||||
case T_USING:
|
||||
return true;
|
||||
|
||||
case T_AT:
|
||||
if (objCEnabled() && LA(2) == T_SYNCHRONIZED)
|
||||
case T_AT_SYNCHRONIZED:
|
||||
if (objCEnabled())
|
||||
return true;
|
||||
|
||||
default:
|
||||
@@ -594,28 +585,23 @@ bool Parser::parseDeclaration(DeclarationAST *&node)
|
||||
return parseTemplateDeclaration(node);
|
||||
|
||||
// ObjcC++
|
||||
case T_AT:
|
||||
if (objCEnabled()) {
|
||||
switch (LA(2)) {
|
||||
case T_CLASS:
|
||||
return parseObjCClassForwardDeclaration(node);
|
||||
case T_AT_CLASS:
|
||||
return parseObjCClassForwardDeclaration(node);
|
||||
|
||||
case T_INTERFACE:
|
||||
return parseObjCInterface(node);
|
||||
case T_AT_INTERFACE:
|
||||
return parseObjCInterface(node);
|
||||
|
||||
case T_PROTOCOL:
|
||||
return parseObjCProtocol(node);
|
||||
case T_AT_PROTOCOL:
|
||||
return parseObjCProtocol(node);
|
||||
|
||||
case T_IMPLEMENTATION:
|
||||
return parseObjCImplementation(node);
|
||||
case T_AT_IMPLEMENTATION:
|
||||
return parseObjCImplementation(node);
|
||||
|
||||
case T_END:
|
||||
// TODO: should this be done here, or higher-up?
|
||||
_translationUnit->error(cursor(), "skip stray token `%s'", tok().spell());
|
||||
consumeToken();
|
||||
break;
|
||||
}
|
||||
}
|
||||
case T_AT_END:
|
||||
// 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__) {
|
||||
@@ -623,14 +609,12 @@ bool Parser::parseDeclaration(DeclarationAST *&node)
|
||||
SpecifierListAST *attributes = 0, **attr = &attributes;
|
||||
while (parseAttributeSpecifier(*attr))
|
||||
attr = &(*attr)->next;
|
||||
if (LA() == T_AT) {
|
||||
if (LA(2) == T_INTERFACE)
|
||||
return parseObjCInterface(node, attributes);
|
||||
else if (LA(2) == T_PROTOCOL)
|
||||
return parseObjCProtocol(node, attributes);
|
||||
else if (LA(2) == T_PROPERTY)
|
||||
return parseObjCPropertyDeclaration(node, attributes);
|
||||
}
|
||||
if (LA() == T_AT_INTERFACE)
|
||||
return parseObjCInterface(node, attributes);
|
||||
else if (LA() == T_AT_PROTOCOL)
|
||||
return parseObjCProtocol(node, attributes);
|
||||
else if (LA() == T_AT_PROPERTY)
|
||||
return parseObjCPropertyDeclaration(node, attributes);
|
||||
rewind(start);
|
||||
}
|
||||
|
||||
@@ -2431,6 +2415,9 @@ bool Parser::parseStatement(StatementAST *&node)
|
||||
return true;
|
||||
}
|
||||
|
||||
case T_AT_SYNCHRONIZED:
|
||||
return objCEnabled() && parseObjCSynchronizedStatement(node);
|
||||
|
||||
case T_Q_D:
|
||||
case T_Q_Q: {
|
||||
QtMemberDeclarationAST *ast = new (_pool) QtMemberDeclarationAST;
|
||||
@@ -2441,10 +2428,6 @@ bool Parser::parseStatement(StatementAST *&node)
|
||||
node = ast;
|
||||
} return true;
|
||||
|
||||
case T_AT:
|
||||
return objCEnabled() && LA(2) == T_SYNCHRONIZED
|
||||
&& parseObjCSynchronizedStatement(node);
|
||||
|
||||
default:
|
||||
if (LA() == T_IDENTIFIER && LA(2) == T_COLON)
|
||||
return parseLabeledStatement(node);
|
||||
@@ -3487,7 +3470,10 @@ bool Parser::parsePrimaryExpression(ExpressionAST *&node)
|
||||
return parseQtMethod(node);
|
||||
|
||||
case T_LBRACKET:
|
||||
case T_AT:
|
||||
case T_AT_STRING_LITERAL:
|
||||
case T_AT_ENCODE:
|
||||
case T_AT_PROTOCOL:
|
||||
case T_AT_SELECTOR:
|
||||
return parseObjCExpression(node);
|
||||
|
||||
default: {
|
||||
@@ -3507,22 +3493,20 @@ bool Parser::parsePrimaryExpression(ExpressionAST *&node)
|
||||
bool Parser::parseObjCExpression(ExpressionAST *&node)
|
||||
{
|
||||
DEBUG_THIS_RULE();
|
||||
if (LA() == T_LBRACKET)
|
||||
return parseObjCMessageExpression(node);
|
||||
if (LA() != T_AT)
|
||||
return false;
|
||||
|
||||
switch (LA(2)) {
|
||||
case T_ENCODE:
|
||||
switch (LA()) {
|
||||
case T_AT_ENCODE:
|
||||
return parseObjCEncodeExpression(node);
|
||||
|
||||
case T_PROTOCOL:
|
||||
case T_AT_PROTOCOL:
|
||||
return parseObjCProtocolExpression(node);
|
||||
|
||||
case T_SELECTOR:
|
||||
case T_AT_SELECTOR:
|
||||
return parseObjCSelectorExpression(node);
|
||||
|
||||
case T_STRING_LITERAL:
|
||||
case T_LBRACKET:
|
||||
return parseObjCMessageExpression(node);
|
||||
|
||||
case T_AT_STRING_LITERAL:
|
||||
return parseObjCStringLiteral(node);
|
||||
|
||||
default:
|
||||
@@ -3531,54 +3515,30 @@ bool Parser::parseObjCExpression(ExpressionAST *&node)
|
||||
return false;
|
||||
}
|
||||
|
||||
// We allow for the same kind of Objective-C string literals as clang, NOT as
|
||||
// GCC. So, we/clang allow(s):
|
||||
// NSLog(@"foo");
|
||||
// NSLog(@
|
||||
// "foo");
|
||||
// NSLog(@"foo"
|
||||
// "bar");
|
||||
// NSLog(@"foo"
|
||||
// @"bar');
|
||||
//
|
||||
// What we don't grok, but GCC also allows:
|
||||
// NSLog(@"foo"
|
||||
// @@"bar");
|
||||
// NSLog(@"foo"
|
||||
// "bar"@@);
|
||||
bool Parser::parseObjCStringLiteral(ExpressionAST *&node)
|
||||
{
|
||||
DEBUG_THIS_RULE();
|
||||
if (LA() != T_AT || LA(2) != T_STRING_LITERAL)
|
||||
if (LA() != T_AT_STRING_LITERAL)
|
||||
return false;
|
||||
|
||||
StringLiteralAST **ast = 0;
|
||||
while (LA()) {
|
||||
if (LA() == T_AT && LA(2) == T_STRING_LITERAL) {
|
||||
*ast = new (_pool) StringLiteralAST;
|
||||
(*ast)->at_token = consumeToken();
|
||||
(*ast)->literal_token = consumeToken();
|
||||
ast = &(*ast)->next;
|
||||
} else if (LA() == T_STRING_LITERAL) {
|
||||
*ast = new (_pool) StringLiteralAST;
|
||||
(*ast)->literal_token = consumeToken();
|
||||
ast = &(*ast)->next;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
StringLiteralAST **ast = reinterpret_cast<StringLiteralAST **> (&node);
|
||||
|
||||
while (LA() == T_AT_STRING_LITERAL) {
|
||||
*ast = new (_pool) StringLiteralAST;
|
||||
(*ast)->literal_token = consumeToken();
|
||||
ast = &(*ast)->next;
|
||||
}
|
||||
node = *ast;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Parser::parseObjCSynchronizedStatement(StatementAST *&node)
|
||||
{
|
||||
DEBUG_THIS_RULE();
|
||||
if (LA() == T_AT || LA(2) != T_SYNCHRONIZED)
|
||||
if (LA() != T_AT_SYNCHRONIZED)
|
||||
return false;
|
||||
|
||||
ObjCSynchronizedStatementAST *ast = new (_pool) ObjCSynchronizedStatementAST;
|
||||
ast->at_token = consumeToken();
|
||||
|
||||
ast->synchronized_token = consumeToken();
|
||||
match(T_LPAREN, &ast->lparen_token);
|
||||
parseExpression(ast->synchronized_object);
|
||||
@@ -3592,11 +3552,10 @@ bool Parser::parseObjCSynchronizedStatement(StatementAST *&node)
|
||||
bool Parser::parseObjCEncodeExpression(ExpressionAST *&node)
|
||||
{
|
||||
DEBUG_THIS_RULE();
|
||||
if (LA() != T_AT || LA(2) != T_ENCODE)
|
||||
if (LA() != T_AT_ENCODE)
|
||||
return false;
|
||||
|
||||
ObjCEncodeExpressionAST *ast = new (_pool) ObjCEncodeExpressionAST;
|
||||
ast->at_token = consumeToken();
|
||||
ast->encode_token = consumeToken();
|
||||
parseObjCTypeName(ast->type_name);
|
||||
node = ast;
|
||||
@@ -3606,11 +3565,10 @@ bool Parser::parseObjCEncodeExpression(ExpressionAST *&node)
|
||||
bool Parser::parseObjCProtocolExpression(ExpressionAST *&node)
|
||||
{
|
||||
DEBUG_THIS_RULE();
|
||||
if (LA() != T_AT || LA(2) != T_PROTOCOL)
|
||||
if (LA() != T_AT_PROTOCOL)
|
||||
return false;
|
||||
|
||||
ObjCProtocolExpressionAST *ast = new (_pool) ObjCProtocolExpressionAST;
|
||||
ast->at_token = consumeToken();
|
||||
ast->protocol_token = consumeToken();
|
||||
match(T_LPAREN, &ast->lparen_token);
|
||||
match(T_IDENTIFIER, &ast->identifier_token);
|
||||
@@ -3622,11 +3580,10 @@ bool Parser::parseObjCProtocolExpression(ExpressionAST *&node)
|
||||
bool Parser::parseObjCSelectorExpression(ExpressionAST *&node)
|
||||
{
|
||||
DEBUG_THIS_RULE();
|
||||
if (LA() != T_AT || LA(2) != T_SELECTOR)
|
||||
if (LA() != T_AT_SELECTOR)
|
||||
return false;
|
||||
|
||||
ObjCSelectorExpressionAST *ast = new (_pool) ObjCSelectorExpressionAST;
|
||||
ast->at_token = consumeToken();
|
||||
ast->selector_token = consumeToken();
|
||||
match(T_LPAREN, &ast->lparen_token);
|
||||
|
||||
@@ -4536,11 +4493,11 @@ bool Parser::lookAtObjCSelector() const
|
||||
bool Parser::parseObjCClassForwardDeclaration(DeclarationAST *&node)
|
||||
{
|
||||
DEBUG_THIS_RULE();
|
||||
if (LA() != T_AT || LA(2) != T_CLASS)
|
||||
if (LA() != T_AT_CLASS)
|
||||
return false;
|
||||
|
||||
ObjCClassForwardDeclarationAST *ast = new (_pool) ObjCClassForwardDeclarationAST;
|
||||
ast->at_token = consumeToken();
|
||||
|
||||
ast->class_token = consumeToken();
|
||||
unsigned identifier_token = 0;
|
||||
match(T_IDENTIFIER, &identifier_token);
|
||||
@@ -4592,10 +4549,9 @@ bool Parser::parseObjCInterface(DeclarationAST *&node,
|
||||
attr = &(*attr)->next;
|
||||
}
|
||||
|
||||
if (LA() != T_AT || LA(2) != T_INTERFACE)
|
||||
if (LA() != T_AT_INTERFACE)
|
||||
return false;
|
||||
|
||||
unsigned at_token = consumeToken();
|
||||
unsigned objc_interface_token = consumeToken();
|
||||
unsigned identifier_token = 0;
|
||||
match(T_IDENTIFIER, &identifier_token);
|
||||
@@ -4609,7 +4565,6 @@ bool Parser::parseObjCInterface(DeclarationAST *&node,
|
||||
|
||||
ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST;
|
||||
ast->attribute_list = attributes;
|
||||
ast->at_token = at_token;
|
||||
ast->interface_token = objc_interface_token;
|
||||
SimpleNameAST *class_name = new (_pool) SimpleNameAST;
|
||||
class_name->identifier_token= identifier_token;
|
||||
@@ -4634,8 +4589,7 @@ bool Parser::parseObjCInterface(DeclarationAST *&node,
|
||||
nextMembers = &(*nextMembers)->next;
|
||||
}
|
||||
|
||||
match(T_AT, &ast->ending_at_token);
|
||||
match(T_END, &ast->end_token);
|
||||
match(T_AT_END, &ast->end_token);
|
||||
|
||||
node = ast;
|
||||
return true;
|
||||
@@ -4643,7 +4597,6 @@ bool Parser::parseObjCInterface(DeclarationAST *&node,
|
||||
// a class interface declaration
|
||||
ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST;
|
||||
ast->attribute_list = attributes;
|
||||
ast->at_token = at_token;
|
||||
ast->interface_token = objc_interface_token;
|
||||
SimpleNameAST* class_name = new (_pool) SimpleNameAST;
|
||||
class_name->identifier_token = identifier_token;
|
||||
@@ -4667,8 +4620,7 @@ bool Parser::parseObjCInterface(DeclarationAST *&node,
|
||||
nextMembers = &(*nextMembers)->next;
|
||||
}
|
||||
|
||||
match(T_AT, &ast->ending_at_token);
|
||||
match(T_END, &ast->end_token);
|
||||
match(T_AT_END, &ast->end_token);
|
||||
|
||||
node = ast;
|
||||
return true;
|
||||
@@ -4687,10 +4639,9 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node,
|
||||
attr = &(*attr)->next;
|
||||
}
|
||||
|
||||
if (LA() != T_AT || LA(2) != T_PROTOCOL)
|
||||
if (LA() != T_AT_PROTOCOL)
|
||||
return false;
|
||||
|
||||
unsigned at_token = consumeToken();
|
||||
unsigned protocol_token = consumeToken();
|
||||
unsigned identifier_token = 0;
|
||||
match(T_IDENTIFIER, &identifier_token);
|
||||
@@ -4700,7 +4651,6 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node,
|
||||
|
||||
ObjCProtocolForwardDeclarationAST *ast = new (_pool) ObjCProtocolForwardDeclarationAST;
|
||||
ast->attribute_list = attributes;
|
||||
ast->at_token = at_token;
|
||||
ast->protocol_token = protocol_token;
|
||||
ast->identifier_list = new (_pool) NameListAST;
|
||||
SimpleNameAST *name = new (_pool) SimpleNameAST;
|
||||
@@ -4726,7 +4676,6 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node,
|
||||
// a protocol definition
|
||||
ObjCProtocolDeclarationAST *ast = new (_pool) ObjCProtocolDeclarationAST;
|
||||
ast->attribute_list = attributes;
|
||||
ast->at_token = at_token;
|
||||
ast->protocol_token = protocol_token;
|
||||
SimpleNameAST *name = new (_pool) SimpleNameAST;
|
||||
name->identifier_token = identifier_token;
|
||||
@@ -4742,8 +4691,7 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node,
|
||||
nextMembers = &(*nextMembers)->next;
|
||||
}
|
||||
|
||||
match(T_AT, &ast->ending_at_token);
|
||||
match(T_END, &ast->end_token);
|
||||
match(T_AT_END, &ast->end_token);
|
||||
|
||||
node = ast;
|
||||
return true;
|
||||
@@ -4757,10 +4705,9 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node,
|
||||
bool Parser::parseObjCImplementation(DeclarationAST *&node)
|
||||
{
|
||||
DEBUG_THIS_RULE();
|
||||
if (LA() != T_AT || LA(2) != T_IMPLEMENTATION)
|
||||
if (LA() != T_AT_IMPLEMENTATION)
|
||||
return false;
|
||||
|
||||
unsigned at_token = consumeToken();
|
||||
unsigned implementation_token = consumeToken();
|
||||
unsigned identifier_token = 0;
|
||||
match(T_IDENTIFIER, &identifier_token);
|
||||
@@ -4768,7 +4715,6 @@ bool Parser::parseObjCImplementation(DeclarationAST *&node)
|
||||
if (LA() == T_LPAREN) {
|
||||
// a category implementation
|
||||
ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST;
|
||||
ast->at_token = at_token;
|
||||
ast->implementation_token = implementation_token;
|
||||
SimpleNameAST *class_name = new (_pool) SimpleNameAST;
|
||||
class_name->identifier_token = identifier_token;
|
||||
@@ -4781,14 +4727,12 @@ bool Parser::parseObjCImplementation(DeclarationAST *&node)
|
||||
match(T_RPAREN, &ast->rparen_token);
|
||||
|
||||
parseObjCMethodDefinitionList(ast->member_declaration_list);
|
||||
match(T_AT, &ast->ending_at_token);
|
||||
match(T_END, &ast->end_token);
|
||||
match(T_AT_END, &ast->end_token);
|
||||
|
||||
node = ast;
|
||||
} else {
|
||||
// a class implementation
|
||||
ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST;
|
||||
ast->at_token = at_token;
|
||||
ast->implementation_token = implementation_token;
|
||||
SimpleNameAST *class_name = new (_pool) SimpleNameAST;
|
||||
class_name->identifier_token = identifier_token;
|
||||
@@ -4803,8 +4747,7 @@ bool Parser::parseObjCImplementation(DeclarationAST *&node)
|
||||
|
||||
parseObjClassInstanceVariables(ast->inst_vars_decl);
|
||||
parseObjCMethodDefinitionList(ast->member_declaration_list);
|
||||
match(T_AT, &ast->ending_at_token);
|
||||
match(T_END, &ast->end_token);
|
||||
match(T_AT_END, &ast->end_token);
|
||||
|
||||
node = ast;
|
||||
}
|
||||
@@ -4817,7 +4760,7 @@ bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node)
|
||||
DEBUG_THIS_RULE();
|
||||
DeclarationListAST **next = &node;
|
||||
|
||||
while (LA() && !(LA() == T_AT && LA(2) == T_END)) {
|
||||
while (LA() && LA() != T_AT_END) {
|
||||
unsigned start = cursor();
|
||||
DeclarationAST *declaration = 0;
|
||||
|
||||
@@ -4834,12 +4777,26 @@ bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node)
|
||||
consumeToken();
|
||||
break;
|
||||
|
||||
case T_AT:
|
||||
if (LA(2) == T_SYNTHESIZE) {
|
||||
ObjCSynthesizedPropertiesDeclarationAST *ast = new (_pool) ObjCSynthesizedPropertiesDeclarationAST;
|
||||
ast->synthesized_token = consumeToken();
|
||||
ObjCSynthesizedPropertyListAST *last = new (_pool) ObjCSynthesizedPropertyListAST;
|
||||
ast->property_identifier_list = last;
|
||||
case T_AT_SYNTHESIZE: {
|
||||
ObjCSynthesizedPropertiesDeclarationAST *ast = new (_pool) ObjCSynthesizedPropertiesDeclarationAST;
|
||||
ast->synthesized_token = consumeToken();
|
||||
ObjCSynthesizedPropertyListAST *last = new (_pool) ObjCSynthesizedPropertyListAST;
|
||||
ast->property_identifier_list = last;
|
||||
last->value = new (_pool) ObjCSynthesizedPropertyAST;
|
||||
match(T_IDENTIFIER, &last->value->property_identifier_token);
|
||||
|
||||
if (LA() == T_EQUAL) {
|
||||
last->value->equals_token = consumeToken();
|
||||
|
||||
match(T_IDENTIFIER, &last->value->alias_identifier_token);
|
||||
}
|
||||
|
||||
while (LA() == T_COMMA) {
|
||||
consumeToken(); // consume T_COMMA
|
||||
|
||||
last->next = new (_pool) ObjCSynthesizedPropertyListAST;
|
||||
last = last->next;
|
||||
|
||||
last->value = new (_pool) ObjCSynthesizedPropertyAST;
|
||||
match(T_IDENTIFIER, &last->value->property_identifier_token);
|
||||
|
||||
@@ -4848,52 +4805,39 @@ bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node)
|
||||
|
||||
match(T_IDENTIFIER, &last->value->alias_identifier_token);
|
||||
}
|
||||
|
||||
while (LA() == T_COMMA) {
|
||||
consumeToken(); // consume T_COMMA
|
||||
|
||||
last->next = new (_pool) ObjCSynthesizedPropertyListAST;
|
||||
last = last->next;
|
||||
|
||||
last->value = new (_pool) ObjCSynthesizedPropertyAST;
|
||||
match(T_IDENTIFIER, &last->value->property_identifier_token);
|
||||
|
||||
if (LA() == T_EQUAL) {
|
||||
last->value->equals_token = consumeToken();
|
||||
|
||||
match(T_IDENTIFIER, &last->value->alias_identifier_token);
|
||||
}
|
||||
}
|
||||
|
||||
match(T_SEMICOLON, &ast->semicolon_token);
|
||||
|
||||
declaration = ast;
|
||||
break;
|
||||
} else if (LA(2) == T_DYNAMIC) {
|
||||
ObjCDynamicPropertiesDeclarationAST *ast = new (_pool) ObjCDynamicPropertiesDeclarationAST;
|
||||
ast->dynamic_token = consumeToken();
|
||||
ast->property_identifier_list = new (_pool) NameListAST;
|
||||
SimpleNameAST *name = new (_pool) SimpleNameAST;
|
||||
match(T_IDENTIFIER, &name->identifier_token);
|
||||
ast->property_identifier_list->value = name;
|
||||
|
||||
NameListAST *last = ast->property_identifier_list;
|
||||
while (LA() == T_COMMA) {
|
||||
consumeToken(); // consume T_COMMA
|
||||
|
||||
last->next = new (_pool) NameListAST;
|
||||
last = last->next;
|
||||
name = new (_pool) SimpleNameAST;
|
||||
match(T_IDENTIFIER, &name->identifier_token);
|
||||
last->value = name;
|
||||
}
|
||||
|
||||
match(T_SEMICOLON, &ast->semicolon_token);
|
||||
|
||||
declaration = ast;
|
||||
break;
|
||||
}
|
||||
|
||||
match(T_SEMICOLON, &ast->semicolon_token);
|
||||
|
||||
declaration = ast;
|
||||
break;
|
||||
}
|
||||
|
||||
case T_AT_DYNAMIC: {
|
||||
ObjCDynamicPropertiesDeclarationAST *ast = new (_pool) ObjCDynamicPropertiesDeclarationAST;
|
||||
ast->dynamic_token = consumeToken();
|
||||
ast->property_identifier_list = new (_pool) NameListAST;
|
||||
SimpleNameAST *name = new (_pool) SimpleNameAST;
|
||||
match(T_IDENTIFIER, &name->identifier_token);
|
||||
ast->property_identifier_list->value = name;
|
||||
|
||||
NameListAST *last = ast->property_identifier_list;
|
||||
while (LA() == T_COMMA) {
|
||||
consumeToken(); // consume T_COMMA
|
||||
|
||||
last->next = new (_pool) NameListAST;
|
||||
last = last->next;
|
||||
name = new (_pool) SimpleNameAST;
|
||||
match(T_IDENTIFIER, &name->identifier_token);
|
||||
last->value = name;
|
||||
}
|
||||
|
||||
match(T_SEMICOLON, &ast->semicolon_token);
|
||||
|
||||
declaration = ast;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
if (LA() == T_EXTERN && LA(2) == T_STRING_LITERAL) {
|
||||
parseDeclaration(declaration);
|
||||
@@ -5023,6 +4967,22 @@ bool Parser::parseObjCInterfaceMemberDeclaration(DeclarationAST *&node)
|
||||
{
|
||||
DEBUG_THIS_RULE();
|
||||
switch (LA()) {
|
||||
case T_AT_END:
|
||||
return false;
|
||||
|
||||
case T_AT_REQUIRED:
|
||||
case T_AT_OPTIONAL:
|
||||
consumeToken();
|
||||
return true;
|
||||
|
||||
case T_SEMICOLON:
|
||||
consumeToken();
|
||||
return true;
|
||||
|
||||
case T_AT_PROPERTY: {
|
||||
return parseObjCPropertyDeclaration(node);
|
||||
}
|
||||
|
||||
case T_PLUS:
|
||||
case T_MINUS: {
|
||||
ObjCMethodDeclarationAST *ast = new (_pool) ObjCMethodDeclarationAST;
|
||||
@@ -5042,30 +5002,6 @@ bool Parser::parseObjCInterfaceMemberDeclaration(DeclarationAST *&node)
|
||||
return parseSimpleDeclaration(node, /*accept struct declarators */ true);
|
||||
}
|
||||
|
||||
case T_AT:
|
||||
switch (LA(2)) {
|
||||
case T_END:
|
||||
return false;
|
||||
|
||||
case T_REQUIRED:
|
||||
case T_OPTIONAL:
|
||||
// ### FIXME
|
||||
consumeToken();
|
||||
return true;
|
||||
|
||||
case T_SEMICOLON:
|
||||
consumeToken();
|
||||
return true;
|
||||
|
||||
case T_PROPERTY: {
|
||||
return parseObjCPropertyDeclaration(node);
|
||||
|
||||
default: {
|
||||
// INTENTIONAL FALL-THROUGH!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default: {
|
||||
return parseSimpleDeclaration(node, /*accept struct declarators */ true);
|
||||
} // default
|
||||
@@ -5079,23 +5015,20 @@ bool Parser::parseObjCInterfaceMemberDeclaration(DeclarationAST *&node)
|
||||
bool Parser::parseObjCInstanceVariableDeclaration(DeclarationAST *&node)
|
||||
{
|
||||
DEBUG_THIS_RULE();
|
||||
if (LA() == T_AT) {
|
||||
switch (LA(2)) {
|
||||
case T_PRIVATE:
|
||||
case T_PROTECTED:
|
||||
case T_PUBLIC:
|
||||
case T_PACKAGE: {
|
||||
ObjCVisibilityDeclarationAST *ast =
|
||||
new (_pool) ObjCVisibilityDeclarationAST;
|
||||
ast->at_token = consumeToken();
|
||||
ast->visibility_token = consumeToken();
|
||||
node = ast;
|
||||
return true;
|
||||
}
|
||||
switch (LA()) {
|
||||
case T_AT_PRIVATE:
|
||||
case T_AT_PROTECTED:
|
||||
case T_AT_PUBLIC:
|
||||
case T_AT_PACKAGE: {
|
||||
ObjCVisibilityDeclarationAST *ast = new (_pool) ObjCVisibilityDeclarationAST;
|
||||
ast->visibility_token = consumeToken();
|
||||
node = ast;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return parseSimpleDeclaration(node, true);
|
||||
default:
|
||||
return parseSimpleDeclaration(node, true);
|
||||
}
|
||||
}
|
||||
|
||||
// objc-property-declaration ::=
|
||||
@@ -5104,12 +5037,11 @@ bool Parser::parseObjCInstanceVariableDeclaration(DeclarationAST *&node)
|
||||
bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&node, SpecifierListAST *attributes)
|
||||
{
|
||||
DEBUG_THIS_RULE();
|
||||
if (LA() != T_AT || LA(2) != T_PROPERTY)
|
||||
if (LA() != T_AT_PROPERTY)
|
||||
return false;
|
||||
|
||||
ObjCPropertyDeclarationAST *ast = new (_pool) ObjCPropertyDeclarationAST;
|
||||
ast->attribute_list = attributes;
|
||||
ast->at_token = consumeToken();
|
||||
ast->property_token = consumeToken();
|
||||
|
||||
if (LA() == T_LPAREN) {
|
||||
|
Reference in New Issue
Block a user