summaryrefslogtreecommitdiff
path: root/shared/cplusplus
diff options
context:
space:
mode:
Diffstat (limited to 'shared/cplusplus')
-rw-r--r--shared/cplusplus/AST.cpp12
-rw-r--r--shared/cplusplus/AST.h1
-rw-r--r--shared/cplusplus/Parser.cpp703
-rw-r--r--shared/cplusplus/Parser.h46
-rw-r--r--shared/cplusplus/Token.h11
5 files changed, 339 insertions, 434 deletions
diff --git a/shared/cplusplus/AST.cpp b/shared/cplusplus/AST.cpp
index d112f9ab53..11be99ea48 100644
--- a/shared/cplusplus/AST.cpp
+++ b/shared/cplusplus/AST.cpp
@@ -3898,6 +3898,8 @@ void IdentifierListAST::accept0(ASTVisitor *visitor)
unsigned ObjCClassDeclarationAST::firstToken() const
{
+ if (attributes)
+ return attributes->firstToken();
return class_token;
}
@@ -3911,12 +3913,19 @@ unsigned ObjCClassDeclarationAST::lastToken() const
return it->identifier_token + 1;
}
+ for (SpecifierAST *it = attributes; it; it = it->next) {
+ if (! it->next)
+ return it->lastToken();
+ }
+
return class_token + 1;
}
ObjCClassDeclarationAST *ObjCClassDeclarationAST::clone(MemoryPool *pool) const
{
ObjCClassDeclarationAST *ast = new (pool) ObjCClassDeclarationAST;
+ if (attributes)
+ ast->attributes = attributes->clone(pool);
ast->class_token = class_token;
if (identifier_list)
ast->identifier_list = identifier_list->clone(pool);
@@ -3927,6 +3936,9 @@ ObjCClassDeclarationAST *ObjCClassDeclarationAST::clone(MemoryPool *pool) const
void ObjCClassDeclarationAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
+ for (SpecifierAST *it = attributes; it; it = it->next) {
+ accept(it, visitor);
+ }
}
}
diff --git a/shared/cplusplus/AST.h b/shared/cplusplus/AST.h
index d03cd3ff82..6607e76805 100644
--- a/shared/cplusplus/AST.h
+++ b/shared/cplusplus/AST.h
@@ -1949,6 +1949,7 @@ protected:
class CPLUSPLUS_EXPORT ObjCClassDeclarationAST: public DeclarationAST
{
public:
+ SpecifierAST *attributes;
unsigned class_token;
IdentifierListAST *identifier_list;
unsigned semicolon_token;
diff --git a/shared/cplusplus/Parser.cpp b/shared/cplusplus/Parser.cpp
index 8e15a220be..6911fd4f9c 100644
--- a/shared/cplusplus/Parser.cpp
+++ b/shared/cplusplus/Parser.cpp
@@ -403,39 +403,45 @@ bool Parser::parseDeclaration(DeclarationAST *&node)
case T_EXPORT:
return parseTemplateDeclaration(node);
- // objc++
- case T_AT_IMPLEMENTATION:
- return parseObjCClassImplementation(node);
-
+ // ObjcC++
case T_AT_CLASS:
return parseObjCClassDeclaration(node);
case T_AT_INTERFACE:
- return parseObjCInterfaceDeclaration(node);
+ return parseObjCInterface(node);
case T_AT_PROTOCOL:
- return parseObjCProtocolDeclaration(node);
+ return parseObjCProtocol(node);
case T_AT_END:
- return parseObjCEndDeclaration(node);
-
- case T_AT_COMPATIBILITY_ALIAS:
- return parseObjCAliasDeclaration(node);
-
- case T_AT_SYNTHESIZE:
- return parseObjCPropertySynthesize(node);
+ return parseObjCEnd(node);
- case T_AT_DYNAMIC:
- return parseObjCPropertyDynamic(node);
+ default: {
+ if (_objCEnabled && LA() == T___ATTRIBUTE__) {
+ const unsigned start = cursor();
+ SpecifierAST *attributes = 0, **attr = &attributes;
+ while (parseAttributeSpecifier(*attr))
+ attr = &(*attr)->next;
+ 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);
+ }
- default:
if (LA() == T_EXTERN && LA(2) == T_TEMPLATE)
return parseTemplateDeclaration(node);
else if (LA() == T_EXTERN && LA(2) == T_STRING_LITERAL)
return parseLinkageSpecification(node);
else
return parseSimpleDeclaration(node);
+ } break; // default
+
} // end switch
+
+ return false;
}
bool Parser::parseLinkageSpecification(DeclarationAST *&node)
@@ -2543,16 +2549,7 @@ bool Parser::parsePrimaryExpression(ExpressionAST *&node)
case T_SLOT:
return parseQtMethod(node);
- case T_AT_ENCODE:
- case T_AT_PROTOCOL:
- case T_AT_SELECTOR:
- case T_AT_STRING_LITERAL:
- return parseObjCExpression(node);
-
default: {
- if (_objCEnabled && LA() == T_LBRACKET)
- return parseObjCExpression(node);
-
unsigned startOfName = cursor();
NameAST *name = 0;
if (parseName(name)) {
@@ -3303,513 +3300,417 @@ bool Parser::parseThrowExpression(ExpressionAST *&node)
return false;
}
-bool Parser::parseObjCClassImplementation(DeclarationAST *&)
+bool Parser::lookAtObjCSelector() const
{
- if (LA() != T_AT_IMPLEMENTATION)
- return false;
-
- /*unsigned implementation_token = */ consumeToken();
- unsigned identifier_token = 0;
- match(T_IDENTIFIER, &identifier_token);
+ switch (LA()) {
+ case T_IDENTIFIER:
+ case T_OR:
+ case T_AND:
+ case T_NOT:
+ case T_XOR:
+ case T_BITOR:
+ case T_COMPL:
+ case T_OR_EQ:
+ case T_AND_EQ:
+ case T_BITAND:
+ case T_NOT_EQ:
+ case T_XOR_EQ:
+ return true;
- if (LA() == T_COLON) {
- /*unsigned colon_token = */ consumeToken();
- unsigned superclass_name_token = 0;
- match(T_IDENTIFIER, &superclass_name_token);
- } else if (LA() == T_LPAREN) {
- /*unsigned lparen_token = */ consumeToken();
- unsigned category_name_token = 0;
- if (LA() == T_IDENTIFIER)
- category_name_token = consumeToken();
- unsigned rparen_token = 0;
- match(T_RPAREN, &rparen_token);
- }
+ default:
+ if (tok().isKeyword())
+ return true;
+ } // switch
- _inObjCImplementationContext = true;
- parseObjCMethodDefinitionList();
- return true;
+ return false;
}
+// objc-class-declaraton ::= T_AT_CLASS (T_IDENTIFIER @ T_COMMA) T_SEMICOLON
+//
bool Parser::parseObjCClassDeclaration(DeclarationAST *&node)
{
if (LA() != T_AT_CLASS)
return false;
- ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST;
- ast->class_token = consumeToken();
- parseObjCIdentifierList(ast->identifier_list);
- match(T_SEMICOLON, &ast->semicolon_token);
- node = ast;
+ unsigned objc_class_token = consumeToken();
+ unsigned identifier_token = 0;
+ match(T_IDENTIFIER, &identifier_token);
+ while (LA() == T_COMMA) {
+ consumeToken(); // skip T_COMMA
+ match(T_IDENTIFIER, &identifier_token);
+ }
+
+ unsigned semicolon_token = 0;
+ match(T_SEMICOLON, &semicolon_token);
return true;
}
-bool Parser::parseObjCInterfaceDeclaration(DeclarationAST *&)
+// objc-interface ::= attribute-specifier-list-opt objc-class-interface
+// objc-interface ::= objc-category-interface
+//
+// objc-class-interface ::= T_AT_INTERFACE T_IDENTIFIER (T_COLON T_IDENTIFIER)?
+// objc-protocol-refs-opt
+// objc-class-instance-variables-opt
+// objc-interface-declaration-list
+// T_AT_END
+//
+// objc-category-interface ::= T_AT_INTERFACE T_IDENTIFIER
+// T_LPAREN T_IDENTIFIER? T_RPAREN
+// objc-protocol-refs-opt
+// objc-interface-declaration-list
+// T_AT_END
+//
+bool Parser::parseObjCInterface(DeclarationAST *&node,
+ SpecifierAST *attributes)
{
+ if (! attributes && LA() == T___ATTRIBUTE__) {
+ SpecifierAST **attr = &attributes;
+ while (parseAttributeSpecifier(*attr))
+ attr = &(*attr)->next;
+ }
+
if (LA() != T_AT_INTERFACE)
return false;
- /*unsigned interface_token = */ consumeToken();
- unsigned interface_name_token = 0;
- match(T_IDENTIFIER, &interface_name_token);
+ unsigned objc_interface_token = consumeToken();
+ unsigned identifier_token = 0;
+ match(T_IDENTIFIER, &identifier_token);
+
if (LA() == T_LPAREN) {
- // category interface
- /*unsigned lparen_token = */ consumeToken();
- unsigned catagory_name_token = 0;
+ // a category interface
+
+ if (attributes)
+ _translationUnit->error(attributes->firstToken(),
+ "invalid attributes for category interface declaration");
+
+ unsigned lparen_token = 0, rparen_token = 0;
+ match(T_LPAREN, &lparen_token);
if (LA() == T_IDENTIFIER)
- catagory_name_token = consumeToken();
- unsigned rparen_token = 0;
+ consumeToken();
+
match(T_RPAREN, &rparen_token);
+
parseObjCProtocolRefs();
- parseObjCClassInstanceVariables();
- parseObjCInterfaceDeclList();
- unsigned end_token = 0;
- match(T_AT_END, &end_token);
- return true;
- } else {
- // class interface
- unsigned colon_token = 0;
- unsigned super_class_token = 0;
- if (LA() == T_COLON) {
- colon_token = consumeToken();
- match(T_IDENTIFIER, &super_class_token);
+ while (parseObjCInterfaceMemberDeclaration()) {
}
- parseObjCProtocolRefs();
- parseObjCInterfaceDeclList();
- unsigned end_token = 0;
- match(T_AT_END, &end_token);
+ unsigned objc_end_token = 0;
+ match(T_AT_END, &objc_end_token);
return true;
}
- return false;
-}
-
-bool Parser::parseObjCProtocolDeclaration(DeclarationAST *&)
-{
- return false;
-}
-
-bool Parser::parseObjCEndDeclaration(DeclarationAST *&)
-{
- if (LA() != T_AT_END)
- return false;
-
- unsigned end_token = consumeToken();
- if (! _inObjCImplementationContext) {
- _translationUnit->warning(end_token,
- "@end must appear in an @implementation context");
+ // a class interface declaration
+ if (LA() == T_COLON) {
+ consumeToken();
+ unsigned identifier_token = 0;
+ match(T_IDENTIFIER, &identifier_token);
}
- _inObjCImplementationContext = false;
+ parseObjCProtocolRefs();
+ parseObjClassInstanceVariables();
+ while (parseObjCInterfaceMemberDeclaration()) {
+ }
+ unsigned objc_end_token = 0;
+ match(T_AT_END, &objc_end_token);
return true;
}
-bool Parser::parseObjCAliasDeclaration(DeclarationAST *&)
+// objc-protocol ::= T_AT_PROTOCOL (T_IDENTIFIER @ T_COMMA) T_SEMICOLON
+//
+bool Parser::parseObjCProtocol(DeclarationAST *&node,
+ SpecifierAST *attributes)
{
- return false;
-}
+ if (! attributes && LA() == T___ATTRIBUTE__) {
+ SpecifierAST **attr = &attributes;
+ while (parseAttributeSpecifier(*attr))
+ attr = &(*attr)->next;
+ }
-bool Parser::parseObjCPropertySynthesize(DeclarationAST *&)
-{
- return false;
-}
+ if (LA() != T_AT_PROTOCOL)
+ return false;
-bool Parser::parseObjCPropertyDynamic(DeclarationAST *&)
-{
- return false;
-}
+ unsigned objc_protocol_token = consumeToken();
+ unsigned identifier_token = 0;
+ match(T_IDENTIFIER, &identifier_token);
+
+ if (LA() == T_COMMA || LA() == T_SEMICOLON) {
+ // a protocol forward declaration
-bool Parser::parseObjCIdentifierList(IdentifierListAST *&node)
-{
- if (LA() == T_IDENTIFIER) {
- IdentifierListAST **it = &node;
- IdentifierListAST *id = new (_pool) IdentifierListAST;
- id->identifier_token = consumeToken();
- *it = id;
while (LA() == T_COMMA) {
consumeToken();
- if (LA() == T_IDENTIFIER) {
- it = &(*it)->next;
- IdentifierListAST *id = new (_pool) IdentifierListAST;
- id->identifier_token = consumeToken();
- *it = id;
- }
+ match(T_IDENTIFIER, &identifier_token);
}
+ unsigned semicolon_token = 0;
+ match(T_SEMICOLON, &semicolon_token);
return true;
}
- return false;
-}
-bool Parser::parseObjCProtocolRefs()
-{
- return false;
-}
+ // a protocol definition
+ parseObjCProtocolRefs();
-bool Parser::parseObjCClassInstanceVariables()
-{
- return false;
-}
-
-bool Parser::parseObjCInterfaceDeclList()
-{
- unsigned saved = cursor();
- while (LA() != T_AT_END && parseObjCInterfaceMemberDeclaration()) {
- if (saved == cursor())
- consumeToken(); // skip a token
+ while (parseObjCInterfaceMemberDeclaration()) {
}
- return true;
-}
-
-bool Parser::parseObjCInterfaceMemberDeclaration()
-{
- switch (LA()) {
- case T_SEMICOLON:
- consumeToken();
- return true;
-
- case T_AT_REQUIRED:
- case T_AT_OPTIONAL:
- consumeToken();
- return true;
-
- case T_PLUS:
- case T_MINUS:
- return parseObjCMethodPrototype();
-
- default: {
- DeclarationAST *declaration = 0;
- if (parseDeclaration(declaration))
- return true;
- } // default
- } // switch
+ unsigned objc_end_token = 0;
+ match(T_AT_END, &objc_end_token);
- return false;
+ return true;
}
-bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&)
-{
- return false;
-}
-bool Parser::parseObjCMethodPrototype()
+// objc-protocol-refs ::= T_LESS (T_IDENTIFIER @ T_COMMA) T_GREATER
+//
+bool Parser::parseObjCProtocolRefs()
{
- if (LA() != T_PLUS && LA() != T_MINUS)
+ if (LA() != T_LESS)
return false;
-
- // instance or class method?
- /*unsigned method_type_token = */ consumeToken();
-
- SpecifierAST *attributes = 0, **attr = &attributes;
- while (parseAttributeSpecifier(*attr))
- attr = &(*attr)->next;
-
- return false;
+ unsigned less_token = 0, greater_token = 0;
+ unsigned identifier_token = 0;
+ match(T_LESS, &less_token);
+ match(T_IDENTIFIER, &identifier_token);
+ while (LA() == T_COMMA) {
+ consumeToken();
+ match(T_IDENTIFIER, &identifier_token);
+ }
+ match(T_GREATER, &greater_token);
+ return true;
}
-bool Parser::parseObjCExpression(ExpressionAST *&node)
+// objc-class-instance-variables ::= T_LBRACE
+// objc-instance-variable-decl-list-opt
+// T_RBRACE
+//
+bool Parser::parseObjClassInstanceVariables()
{
- switch (LA()) {
- case T_LBRACKET:
- return parseObjCMessageExpression(node);
+ if (LA() != T_LBRACE)
+ return false;
- case T_AT_STRING_LITERAL:
- return parseObjCStringLiteral(node);
+ unsigned lbrace_token = 0, rbrace_token = 0;
- case T_AT_ENCODE:
- return parseObjCEncodeExpression(node);
+ match(T_LBRACE, &lbrace_token);
+ while (LA()) {
+ if (LA() == T_RBRACE)
+ break;
- case T_AT_PROTOCOL:
- return parseObjCProtocolExpression(node);
+ const unsigned start = cursor();
- case T_AT_SELECTOR:
- return parseObjCSelectorExpression(node);
- }
- return false;
-}
+ DeclarationAST *declaration = 0;
+ parseObjCInstanceVariableDeclaration(declaration);
-bool Parser::parseObjCMessageExpression(ExpressionAST *&)
-{
- if (LA() != T_LBRACKET)
- return false;
+ if (start == cursor()) {
+ // skip stray token.
+ _translationUnit->error(cursor(), "skip stray token `%s'", tok().spell());
+ consumeToken();
+ }
+ }
- /*unsigned lbracket_token = */ consumeToken();
- ExpressionAST *receiver = 0;
- parseObjCMessageReceiver(receiver);
- parseObjCMessageArguments();
- unsigned rbracket_token = 0;
- match(T_RBRACKET, &rbracket_token);
+ match(T_RBRACE, &rbrace_token);
return true;
}
-bool Parser::parseObjCStringLiteral(ExpressionAST *&)
+// objc-interface-declaration ::= T_AT_REQUIRED
+// objc-interface-declaration ::= T_AT_OPTIONAL
+// objc-interface-declaration ::= T_SEMICOLON
+// objc-interface-declaration ::= objc-property-declaration
+// objc-interface-declaration ::= objc-method-prototype
+bool Parser::parseObjCInterfaceMemberDeclaration()
{
- if (LA() != T_AT_STRING_LITERAL)
- return false;
-
- do {
+ switch (LA()) {
+ case T_AT_REQUIRED:
+ case T_AT_OPTIONAL:
consumeToken();
- } while (LA() == T_AT_STRING_LITERAL);
+ return true;
- return true;
-}
+ case T_SEMICOLON:
+ consumeToken();
+ return true;
-bool Parser::parseObjCEncodeExpression(ExpressionAST *&)
-{
- if (LA() != T_AT_ENCODE)
- return false;
+ case T_AT_PROPERTY: {
+ DeclarationAST *declaration = 0;
+ return parseObjCPropertyDeclaration(declaration);
+ }
- /*unsigned encode_token = */ consumeToken();
- unsigned lparen_token = 0, rparen_token = 0;
- match(T_LPAREN, &lparen_token);
- SpecifierAST *type_specifier = 0;
- parseSimpleTypeSpecifier(type_specifier);
- match(T_RPAREN, &rparen_token);
- return true;
-}
+ case T_PLUS:
+ case T_MINUS:
+ return parseObjCMethodPrototype();
-bool Parser::parseObjCProtocolExpression(ExpressionAST *&)
-{
- if (LA() != T_AT_PROTOCOL)
+ default:
return false;
-
- /*unsigned protocol_token = */ consumeToken();
- unsigned protocol_name_token = 0, lparen_token = 0, rparen_token = 0;
- match(T_LPAREN, &lparen_token);
- match(T_IDENTIFIER, &protocol_name_token);
- match(T_RPAREN, &rparen_token);
- return true;
+ }
}
-bool Parser::parseObjCSelectorExpression(ExpressionAST *&)
+// objc-instance-variable-declaration ::= objc-visibility-specifier
+// objc-instance-variable-declaration ::= block-declaration
+//
+bool Parser::parseObjCInstanceVariableDeclaration(DeclarationAST *&node)
{
- if (LA() != T_AT_SELECTOR)
- return false;
+ switch (LA()) {
+ case T_AT_PRIVATE:
+ case T_AT_PROTECTED:
+ case T_AT_PUBLIC:
+ case T_AT_PACKAGE:
+ consumeToken();
+ return true;
- /*unsigned selector_token = */ consumeToken();
- unsigned lparen_token = 0, rparen_token = 0;
- match(T_LPAREN, &lparen_token);
- while (LA(1) == T_IDENTIFIER && LA(2) == T_COLON) {
- /*unsigned identifier_token = */ consumeToken();
- /*unsigned colon_token = */ consumeToken();
+ default:
+ return parseBlockDeclaration(node);
}
- match(T_RPAREN, &rparen_token);
- return true;
-}
-
-bool Parser::parseObjCMessageReceiver(ExpressionAST *&node)
-{
- // ### expression or simple-type-specifier.
- return parseExpression(node);
}
-bool Parser::parseObjCMessageArguments()
+// objc-property-declaration ::=
+// T_AT_PROPERTY T_LPAREN (property-attribute @ T_COMMA) T_RPAREN simple-declaration
+//
+bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&, SpecifierAST *)
{
- if (LA() != T_IDENTIFIER && LA() != T_COLON)
+ if (LA() != T_AT_PROPERTY)
return false;
- unsigned selector_name_token = 0;
-
- if (LA() == T_IDENTIFIER)
- selector_name_token = consumeToken();
-
- if (LA() == T_COLON) {
- /*unsigned colon_token = */ consumeToken();
-
- ExpressionAST *expr = 0;
- parseAssignmentExpression(expr);
-
- while ((LA() == T_IDENTIFIER && LA(2) == T_COLON) || LA() == T_COLON) {
- if (LA() == T_IDENTIFIER)
- consumeToken();
+ unsigned objc_property_token = consumeToken();
- if (LA() == T_COLON)
- consumeToken();
-
- parseAssignmentExpression(expr);
- }
-
- while (LA() == T_COMMA) {
- consumeToken();
- parseAssignmentExpression(expr);
+ if (LA() == T_LPAREN) {
+ unsigned lparen_token = 0, rparen_token = 0;
+ match(T_LPAREN, &lparen_token);
+ while (parseObjCPropertyAttribute()) {
}
+ match(T_RPAREN, &rparen_token);
}
+ DeclarationAST *simple_declaration = 0;
+ parseSimpleDeclaration(simple_declaration, /*accept-struct-declarators = */ false);
return true;
}
-bool Parser::parseObjCMethodDefinitionList()
+// objc-method-prototype ::= (T_PLUS | T_MINUS) objc-method-decl objc-method-attrs-opt
+//
+// objc-method-decl ::= objc-type-name? objc-selector
+// objc-method-decl ::= objc-type-name? objc-keyword-decl-list objc-parmlist-opt
+//
+bool Parser::parseObjCMethodPrototype()
{
- bool done = false;
- while (! done) {
- switch (LA()) {
- case T_EOF_SYMBOL:
- case T_AT_END:
- done = true;
- break;
+ if (LA() != T_PLUS && LA() != T_MINUS)
+ return false;
- case T_PLUS:
- case T_MINUS:
- parseObjCMethodSignature();
- if (LA() == T_SEMICOLON)
- consumeToken();
- break;
+ unsigned method_type_token = consumeToken();
- case T_AT_PROPERTY:
- parseObjCAtProperty();
- break;
-
- case T_SEMICOLON:
- consumeToken();
- break;
+ parseObjCTypeName();
- case T_AT_OPTIONAL:
- consumeToken();
- break;
+ if ((lookAtObjCSelector() && LA(2) == T_COLON) || LA() == T_COLON) {
+ while (parseObjCKeywordDeclaration()) {
+ }
- case T_AT_REQUIRED:
+ while (LA() == T_COMMA) {
consumeToken();
- break;
- case T_TEMPLATE:
- case T_NAMESPACE: {
- DeclarationAST *declaration = 0;
- parseDeclaration(declaration);
- } break;
-
- default: {
- unsigned start = cursor();
- DeclarationAST *declaration = 0;
- if (LA(1) == T_EXTERN && LA(2) == T_STRING_LITERAL) {
- parseLinkageSpecification(declaration);
- } else if (parseBlockDeclaration(declaration)) {
- // ### accept the declaration.
- } else {
- if (cursor() == start) {
- _translationUnit->error(cursor(),
- "stray `%s' between Objective-C++ methods",
- tok().spell());
- consumeToken();
- }
+ if (LA() == T_DOT_DOT_DOT) {
+ consumeToken();
+ break;
}
- } break; // default
- } // switch
+ DeclarationAST *parameter_declaration = 0;
+ parseParameterDeclaration(parameter_declaration);
+ }
+ } else if (lookAtObjCSelector()) {
+ parseObjCSelector();
+ } else {
+ _translationUnit->error(cursor(), "expected a selector");
}
+ SpecifierAST *attributes = 0, **attr = &attributes;
+ while (parseAttributeSpecifier(*attr))
+ attr = &(*attr)->next;
+
return true;
}
-bool Parser::parseObjCMethodSignature()
+// objc-property-attribute ::= getter '=' identifier
+// objc-property-attribute ::= setter '=' identifier ':'
+// objc-property-attribute ::= readonly
+// objc-property-attribute ::= readwrite
+// objc-property-attribute ::= assign
+// objc-property-attribute ::= retain
+// objc-property-attribute ::= copy
+// objc-property-attribute ::= nonatomic
+bool Parser::parseObjCPropertyAttribute()
{
- if (LA() != T_PLUS && LA() != T_MINUS)
+ if (LA() != T_IDENTIFIER)
return false;
- /*unsigned method_type_token = */ consumeToken();
- parseObjCTypeName();
-
- bool first = true;
-
- while (lookAtObjCSelector() || LA() == T_COLON) {
- if (LA() != T_COLON)
- /*selector_name_token = */ consumeToken();
-
- SpecifierAST *attributes = 0, **attr = &attributes;
- while (parseAttributeSpecifier(*attr))
- attr = &(*attr)->next;
-
- if (first) {
- first = false;
-
- if (LA() != T_COLON)
- break;
- }
-
- unsigned colon_token = 0;
- match(T_COLON, &colon_token);
-
- parseObjCTypeName();
-
- unsigned identifier_token = 0;
- match(T_IDENTIFIER, &identifier_token);
-
- while (parseAttributeSpecifier(*attr))
- attr = &(*attr)->next;
- }
-
- // parse the method tail parameters.
- while (LA() == T_COMMA) {
+ unsigned identifier_token = 0;
+ match(T_IDENTIFIER, &identifier_token);
+ if (LA() == T_EQUAL) {
consumeToken();
-
- if (LA() == T_DOT_DOT_DOT) {
+ match(T_IDENTIFIER, &identifier_token);
+ if (LA() == T_COLON)
consumeToken();
- break;
- }
-
- DeclarationAST *parameter_declaration = 0;
- parseParameterDeclaration(parameter_declaration);
}
return true;
}
+// objc-type-name ::= T_LPAREN objc-type-qualifiers-opt type-id T_RPAREN
+//
bool Parser::parseObjCTypeName()
{
if (LA() != T_LPAREN)
return false;
- /*unsigned lparen_token = */ consumeToken();
-
- parseObjCProtocolQualifiers();
-
+ unsigned lparen_token = 0, rparen_token = 0;
+ match(T_LPAREN, &lparen_token);
+ parseObjCTypeQualifiers();
ExpressionAST *type_id = 0;
- if (LA() != T_RPAREN)
- parseTypeId(type_id);
+ parseTypeId(type_id);
+ match(T_RPAREN, &rparen_token);
+ return true;
+}
- SpecifierAST *attributes = 0, **attr = &attributes;
- while (parseAttributeSpecifier(*attr))
- attr = &(*attr)->next;
+// objc-selector ::= T_IDENTIFIER | keyword
+//
+bool Parser::parseObjCSelector()
+{
+ if (! lookAtObjCSelector())
+ return false;
- unsigned rparen_token = 0;
- match(T_RPAREN, &rparen_token);
+ consumeToken();
return true;
}
-bool Parser::parseObjCAtProperty()
+// objc-keyword-decl ::= objc-selector? T_COLON objc-type-name? objc-keyword-attributes-opt T_IDENTIFIER
+//
+bool Parser::parseObjCKeywordDeclaration()
{
- if (LA() != T_AT_PROPERTY)
+ if (! (LA() == T_COLON || (lookAtObjCSelector() && LA(2) == T_COLON)))
return false;
- /*unsigned property_token = */ consumeToken();
+ parseObjCSelector();
+
+ unsigned colon_token = 0;
+ match(T_COLON, &colon_token);
+
+ parseObjCTypeName();
+
+ SpecifierAST *attributes = 0, **attr = &attributes;
+ while (parseAttributeSpecifier(*attr))
+ attr = &(*attr)->next;
+
+ unsigned identifier_token = 0;
+ match(T_IDENTIFIER, &identifier_token);
+
return true;
}
-bool Parser::parseObjCProtocolQualifiers()
+bool Parser::parseObjCTypeQualifiers()
{
return false;
}
-bool Parser::lookAtObjCSelector() const
+// objc-end: T_AT_END
+bool Parser::parseObjCEnd(DeclarationAST *&)
{
- switch (LA()) {
- case T_IDENTIFIER:
- case T_OR:
- case T_AND:
- case T_NOT:
- case T_XOR:
- case T_BITOR:
- case T_COMPL:
- case T_OR_EQ:
- case T_AND_EQ:
- case T_BITAND:
- case T_NOT_EQ:
- case T_XOR_EQ:
- return true;
-
- default:
- if (tok().isKeyword())
- return true;
- } // switch
+ if (LA() != T_AT_END)
+ return false;
- return false;
+ consumeToken();
+ return true;
}
+
+
CPLUSPLUS_END_NAMESPACE
diff --git a/shared/cplusplus/Parser.h b/shared/cplusplus/Parser.h
index c943664afe..5132ec5732 100644
--- a/shared/cplusplus/Parser.h
+++ b/shared/cplusplus/Parser.h
@@ -206,46 +206,32 @@ public:
bool parseUsingDirective(DeclarationAST *&node);
bool parseWhileStatement(StatementAST *&node);
+ // Qt MOC run
+ bool parseQtMethod(ExpressionAST *&node);
+
// ObjC++
- bool parseObjCClassImplementation(DeclarationAST *&node);
bool parseObjCClassDeclaration(DeclarationAST *&node);
- bool parseObjCInterfaceDeclaration(DeclarationAST *&node);
- bool parseObjCProtocolDeclaration(DeclarationAST *&node);
- bool parseObjCEndDeclaration(DeclarationAST *&node);
- bool parseObjCAliasDeclaration(DeclarationAST *&node);
- bool parseObjCPropertySynthesize(DeclarationAST *&node);
- bool parseObjCPropertyDynamic(DeclarationAST *&node);
+ bool parseObjCInterface(DeclarationAST *&node,
+ SpecifierAST *attributes = 0);
+ bool parseObjCProtocol(DeclarationAST *&node,
+ SpecifierAST *attributes = 0);
- bool parseObjCIdentifierList(IdentifierListAST *&node);
-
- bool parseObjCPropertyDeclaration(DeclarationAST *&node);
bool parseObjCProtocolRefs();
- bool parseObjCClassInstanceVariables();
+ bool parseObjClassInstanceVariables();
bool parseObjCInterfaceMemberDeclaration();
- bool parseObjCInterfaceDeclList();
+ bool parseObjCInstanceVariableDeclaration(DeclarationAST *&node);
+ bool parseObjCPropertyDeclaration(DeclarationAST *&node,
+ SpecifierAST *attributes = 0);
bool parseObjCMethodPrototype();
-
- bool parseObjCExpression(ExpressionAST *&node);
- bool parseObjCMessageExpression(ExpressionAST *&node);
- bool parseObjCStringLiteral(ExpressionAST *&node);
- bool parseObjCEncodeExpression(ExpressionAST *&node);
- bool parseObjCProtocolExpression(ExpressionAST *&node);
- bool parseObjCSelectorExpression(ExpressionAST *&node);
-
- bool parseObjCMessageReceiver(ExpressionAST *&node);
- bool parseObjCMessageArguments();
-
- bool parseObjCMethodSignature();
- bool parseObjCMethodDefinitionList();
- bool parseObjCAtProperty();
+ bool parseObjCPropertyAttribute();
bool parseObjCTypeName();
- bool parseObjCProtocolQualifiers();
+ bool parseObjCSelector();
+ bool parseObjCKeywordDeclaration();
+ bool parseObjCTypeQualifiers();
+ bool parseObjCEnd(DeclarationAST *&node);
bool lookAtObjCSelector() const;
- // Qt MOC run
- bool parseQtMethod(ExpressionAST *&node);
-
bool skipUntil(int token);
bool skipUntilDeclaration();
bool skipUntilStatement();
diff --git a/shared/cplusplus/Token.h b/shared/cplusplus/Token.h
index d5b6f1a1c0..fdc3298202 100644
--- a/shared/cplusplus/Token.h
+++ b/shared/cplusplus/Token.h
@@ -201,9 +201,9 @@ enum Kind {
T___TYPEOF__,
// obj c++ @ keywords
- T_FIRST_OBJC_KEYWORD,
+ T_FIRST_OBJC_AT_KEYWORD,
- T_AT_CATCH = T_FIRST_OBJC_KEYWORD,
+ T_AT_CATCH = T_FIRST_OBJC_AT_KEYWORD,
T_AT_CLASS,
T_AT_COMPATIBILITY_ALIAS,
T_AT_DEFS,
@@ -228,7 +228,9 @@ enum Kind {
T_AT_THROW,
T_AT_TRY,
- T_FIRST_QT_KEYWORD,
+ T_LAST_OBJC_AT_KEYWORD,
+
+ T_FIRST_QT_KEYWORD = T_LAST_OBJC_AT_KEYWORD,
// Qt keywords
T_SIGNAL = T_FIRST_QT_KEYWORD,
@@ -295,6 +297,9 @@ public:
inline bool isKeyword() const
{ return kind >= T_FIRST_KEYWORD && kind < T_FIRST_QT_KEYWORD; }
+ inline bool isObjCAtKeyword() const
+ { return kind >= T_FIRST_OBJC_AT_KEYWORD && kind < T_LAST_OBJC_AT_KEYWORD; }
+
static const char *name(int kind);
public: