summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/shared/cplusplus/AST.cpp116
-rw-r--r--src/shared/cplusplus/AST.h134
-rw-r--r--src/shared/cplusplus/ASTClone.cpp69
-rw-r--r--src/shared/cplusplus/ASTVisit.cpp66
-rw-r--r--src/shared/cplusplus/ASTVisitor.h12
-rw-r--r--src/shared/cplusplus/ASTfwd.h6
-rw-r--r--src/shared/cplusplus/Parser.cpp152
-rw-r--r--src/shared/cplusplus/Parser.h2
8 files changed, 507 insertions, 50 deletions
diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp
index dc6a505677..3da0dbf464 100644
--- a/src/shared/cplusplus/AST.cpp
+++ b/src/shared/cplusplus/AST.cpp
@@ -1946,6 +1946,122 @@ unsigned ObjCClassDeclarationAST::lastToken() const
return class_token + 1;
}
+unsigned ObjCProtocolDeclarationAST::firstToken() const
+{
+ if (attributes)
+ return attributes->firstToken();
+ return protocol_token;
+}
+
+unsigned ObjCProtocolDeclarationAST::lastToken() const
+{
+ if (semicolon_token)
+ return semicolon_token + 1;
+
+ for (IdentifierListAST *it = identifier_list; it; it = it->next) {
+ if (! it->next && it->identifier_token)
+ return it->identifier_token + 1;
+ }
+
+ for (SpecifierAST *it = attributes; it; it = it->next) {
+ if (! it->next)
+ return it->lastToken();
+ }
+
+ return protocol_token + 1;
+}
+unsigned ObjCClassInterfaceDeclarationAST::firstToken() const
+{
+ if (attributes)
+ return attributes->firstToken();
+ return interface_token;
+}
+
+unsigned ObjCClassInterfaceDeclarationAST::lastToken() const
+{
+ if (end_token) return end_token + 1;
+ if (superclass_identifier_token) return superclass_identifier_token + 1;
+ if (colon_token) return colon_token + 1;
+ if (class_identifier_token) return class_identifier_token + 1;
+
+ for (SpecifierAST *it = attributes; it; it = it->next) {
+ if (! it->next)
+ return it->lastToken();
+ }
+
+ return interface_token + 1;
+}
+
+unsigned ObjCCategoryInterfaceDeclarationAST::firstToken() const
+{
+ return interface_token;
+}
+
+unsigned ObjCCategoryInterfaceDeclarationAST::lastToken() const
+{
+ if (end_token)
+ return end_token + 1;
+
+ if (rparen_token) return rparen_token + 1;
+ if (category_identifier_token) return category_identifier_token + 1;
+ if (lparen_token) return lparen_token + 1;
+ if (class_identifier_token) return class_identifier_token + 1;
+ return interface_token + 1;
+}
+
+unsigned ObjCProtocolDefinitionAST::firstToken() const
+{
+ if (attributes)
+ return attributes->firstToken();
+ return protocol_token;
+}
+
+unsigned ObjCProtocolDefinitionAST::lastToken() const
+{
+ if (end_token)
+ return end_token + 1;
+
+ if (identifier_token)
+ return identifier_token + 1;
+
+ for (SpecifierAST *it = attributes; it; it = it->next) {
+ if (! it->next)
+ return it->lastToken();
+ }
+
+ return protocol_token + 1;
+}
+
+unsigned ObjCProtocolRefsAST::firstToken() const
+{
+ return less_token;
+}
+
+unsigned ObjCProtocolRefsAST::lastToken() const
+{
+ if (greater_token) return greater_token + 1;
+
+ for (IdentifierListAST *it = identifier_list; it; it = it->next) {
+ if (! it->next && it->identifier_token)
+ return it->identifier_token + 1;
+ }
+
+ return less_token + 1;
+}
+
+unsigned ObjCMessageExpressionAST::firstToken() const
+{
+ return lbracket_token;
+}
+
+unsigned ObjCMessageExpressionAST::lastToken() const
+{
+ if (rbracket_token) return rbracket_token + 1;
+
+ // FIXME: TODO
+
+ return lbracket_token + 1;
+}
CPLUSPLUS_END_NAMESPACE
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index d22735eeb1..2e56fc5264 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -197,6 +197,8 @@ public:
virtual WhileStatementAST *asWhileStatement() { return 0; }
virtual IdentifierListAST *asIdentifierList() { return 0; }
virtual ObjCClassDeclarationAST *asObjCClassDeclaration() { return 0; }
+ virtual ObjCProtocolDeclarationAST *asObjCProtocolDeclaration() { return 0; }
+ virtual ObjCProtocolDefinitionAST *asObjCProtocolDefinition() { return 0; }
virtual AST *clone(MemoryPool *pool) const = 0;
@@ -2443,6 +2445,7 @@ class CPLUSPLUS_EXPORT IdentifierListAST: public AST
{
public:
unsigned identifier_token;
+ unsigned comma_token;
IdentifierListAST *next;
public:
@@ -2479,6 +2482,137 @@ protected:
virtual void accept0(ASTVisitor *visitor);
};
+class CPLUSPLUS_EXPORT ObjCClassInterfaceDeclarationAST: public DeclarationAST
+{
+public:
+ SpecifierAST *attributes;
+ unsigned interface_token;
+ unsigned class_identifier_token;
+ unsigned colon_token;
+ unsigned superclass_identifier_token;
+ ObjCProtocolRefsAST *protocol_refs;
+ unsigned end_token;
+
+public:
+ virtual ObjCClassInterfaceDeclarationAST *asObjCClassInterfaceDeclaration()
+ { return this; }
+
+ virtual unsigned firstToken() const;
+ virtual unsigned lastToken() const;
+
+ virtual ObjCClassInterfaceDeclarationAST *clone(MemoryPool *pool) const;
+
+protected:
+ virtual void accept0(ASTVisitor *visitor);
+};
+
+class CPLUSPLUS_EXPORT ObjCCategoryInterfaceDeclarationAST: public DeclarationAST
+{
+public:
+ unsigned interface_token;
+ unsigned class_identifier_token;
+ unsigned lparen_token;
+ unsigned category_identifier_token;
+ unsigned rparen_token;
+ ObjCProtocolRefsAST *protocol_refs;
+ unsigned end_token;
+
+public:
+ virtual ObjCCategoryInterfaceDeclarationAST *asObjCCategoryInterfaceDeclaration()
+ { return this; }
+
+ virtual unsigned firstToken() const;
+ virtual unsigned lastToken() const;
+
+ virtual ObjCCategoryInterfaceDeclarationAST *clone(MemoryPool *pool) const;
+
+protected:
+ virtual void accept0(ASTVisitor *visitor);
+};
+
+class CPLUSPLUS_EXPORT ObjCProtocolDeclarationAST: public DeclarationAST
+{
+public:
+ SpecifierAST *attributes;
+ unsigned protocol_token;
+ IdentifierListAST *identifier_list;
+ unsigned semicolon_token;
+
+public:
+ virtual ObjCProtocolDeclarationAST *asObjCProtocolDeclaration()
+ { return this; }
+
+ virtual unsigned firstToken() const;
+ virtual unsigned lastToken() const;
+
+ virtual ObjCProtocolDeclarationAST *clone(MemoryPool *pool) const;
+
+protected:
+ virtual void accept0(ASTVisitor *visitor);
+};
+
+class CPLUSPLUS_EXPORT ObjCProtocolDefinitionAST: public DeclarationAST
+{
+public:
+ SpecifierAST *attributes;
+ unsigned protocol_token;
+ unsigned identifier_token;
+ ObjCProtocolRefsAST *protocol_refs;
+ unsigned end_token;
+
+public:
+ virtual ObjCProtocolDefinitionAST *asObjCProtocolDefinition()
+ { return this; }
+
+ virtual unsigned firstToken() const;
+ virtual unsigned lastToken() const;
+
+ virtual ObjCProtocolDefinitionAST *clone(MemoryPool *pool) const;
+
+protected:
+ virtual void accept0(ASTVisitor *visitor);
+};
+
+class CPLUSPLUS_EXPORT ObjCProtocolRefsAST: public AST
+{
+public:
+ unsigned less_token;
+ IdentifierListAST *identifier_list;
+ unsigned greater_token;
+
+public:
+ virtual ObjCProtocolRefsAST *asObjCProtocolRefs()
+ { return this; }
+
+ virtual unsigned firstToken() const;
+ virtual unsigned lastToken() const;
+
+ virtual ObjCProtocolRefsAST *clone(MemoryPool *pool) const;
+
+protected:
+ virtual void accept0(ASTVisitor *visitor);
+};
+
+class CPLUSPLUS_EXPORT ObjCMessageExpressionAST: public ExpressionAST
+{
+public:
+ unsigned lbracket_token;
+ // ..
+ unsigned rbracket_token;
+
+public:
+ virtual ObjCMessageExpressionAST *asObjCMessageExpression()
+ { return this; }
+
+ virtual unsigned firstToken() const;
+ virtual unsigned lastToken() const;
+
+ virtual ObjCMessageExpressionAST *clone(MemoryPool *pool) const;
+
+protected:
+ virtual void accept0(ASTVisitor *visitor);
+};
+
CPLUSPLUS_END_NAMESPACE
CPLUSPLUS_END_HEADER
diff --git a/src/shared/cplusplus/ASTClone.cpp b/src/shared/cplusplus/ASTClone.cpp
index 2e446c89ef..b8ceec183c 100644
--- a/src/shared/cplusplus/ASTClone.cpp
+++ b/src/shared/cplusplus/ASTClone.cpp
@@ -1224,4 +1224,73 @@ ObjCClassDeclarationAST *ObjCClassDeclarationAST::clone(MemoryPool *pool) const
return ast;
}
+ObjCClassInterfaceDeclarationAST *ObjCClassInterfaceDeclarationAST::clone(MemoryPool *pool) const
+{
+ ObjCClassInterfaceDeclarationAST *ast = new (pool) ObjCClassInterfaceDeclarationAST;
+ // copy DeclarationAST
+ // copy ObjCClassInterfaceDeclarationAST
+ if (attributes) ast->attributes = attributes->clone(pool);
+ ast->interface_token = interface_token;
+ ast->class_identifier_token = class_identifier_token;
+ ast->colon_token = colon_token;
+ ast->superclass_identifier_token = superclass_identifier_token;
+ if (protocol_refs) ast->protocol_refs = protocol_refs->clone(pool);
+ ast->end_token = end_token;
+ return ast;
+}
+
+ObjCCategoryInterfaceDeclarationAST *ObjCCategoryInterfaceDeclarationAST::clone(MemoryPool *pool) const
+{
+ ObjCCategoryInterfaceDeclarationAST *ast = new (pool) ObjCCategoryInterfaceDeclarationAST;
+ // copy DeclarationAST
+ // copy ObjCCategoryInterfaceDeclarationAST
+ ast->interface_token = interface_token;
+ ast->class_identifier_token = class_identifier_token;
+ if (protocol_refs) ast->protocol_refs = protocol_refs->clone(pool);
+ ast->lparen_token = lparen_token;
+ ast->category_identifier_token = category_identifier_token;
+ ast->rparen_token = rparen_token;
+ ast->end_token = end_token;
+ return ast;
+}
+
+ObjCProtocolDeclarationAST *ObjCProtocolDeclarationAST::clone(MemoryPool *pool) const
+{
+ ObjCProtocolDeclarationAST *ast = new (pool) ObjCProtocolDeclarationAST;
+ if (attributes) ast->attributes = attributes->clone(pool);
+ ast->protocol_token = protocol_token;
+ if (identifier_list) ast->identifier_list = identifier_list;
+ ast->semicolon_token = semicolon_token;
+ return ast;
+}
+
+ObjCProtocolDefinitionAST *ObjCProtocolDefinitionAST::clone(MemoryPool *pool) const
+{
+ ObjCProtocolDefinitionAST *ast = new (pool) ObjCProtocolDefinitionAST;
+ if (attributes) ast->attributes = attributes->clone(pool);
+ ast->protocol_token = protocol_token;
+ ast->identifier_token = identifier_token;
+ if (protocol_refs) ast->protocol_refs = protocol_refs->clone(pool);
+ ast->end_token = end_token;
+ return ast;
+}
+
+ObjCProtocolRefsAST *ObjCProtocolRefsAST::clone(MemoryPool *pool) const
+{
+ ObjCProtocolRefsAST *ast = new (pool) ObjCProtocolRefsAST;
+ ast->less_token = less_token;
+ if (ast->identifier_list) ast->identifier_list = identifier_list->clone(pool);
+ ast->greater_token = greater_token;
+ return ast;
+}
+
+ObjCMessageExpressionAST *ObjCMessageExpressionAST::clone(MemoryPool *pool) const
+{
+ ObjCMessageExpressionAST *ast = new (pool) ObjCMessageExpressionAST;
+ ast->lbracket_token = lbracket_token;
+ // FIXME: TODO
+ ast->rbracket_token = rbracket_token;
+ return ast;
+}
+
CPLUSPLUS_END_NAMESPACE
diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp
index 1673577474..c556b21015 100644
--- a/src/shared/cplusplus/ASTVisit.cpp
+++ b/src/shared/cplusplus/ASTVisit.cpp
@@ -1139,4 +1139,70 @@ void ObjCClassDeclarationAST::accept0(ASTVisitor *visitor)
visitor->endVisit(this);
}
+void ObjCClassInterfaceDeclarationAST::accept0(ASTVisitor *visitor)
+{
+ if (visitor->visit(this)) {
+ // visit ObjCClassInterfaceDeclarationAST
+ for (SpecifierAST *it = attributes; it; it = it->next)
+ accept(it, visitor);
+ accept(protocol_refs, visitor);
+ // visit DeclarationAST
+ }
+ visitor->endVisit(this);
+}
+
+void ObjCCategoryInterfaceDeclarationAST::accept0(ASTVisitor *visitor)
+{
+ if (visitor->visit(this)) {
+ // visit ObjCCategoryInterfaceDeclarationAST
+ accept(protocol_refs, visitor);
+ // visit DeclarationAST
+ }
+ visitor->endVisit(this);
+}
+
+void ObjCProtocolDeclarationAST::accept0(ASTVisitor *visitor)
+{
+ if (visitor->visit(this)) {
+ // visit ObjCProtocolDeclarationAST
+ for (SpecifierAST *it = attributes; it; it = it->next)
+ accept(it, visitor);
+ for (IdentifierListAST *it = identifier_list; it; it = it->next)
+ accept(it, visitor);
+ // visit DeclarationAST
+ }
+ visitor->endVisit(this);
+}
+
+void ObjCProtocolDefinitionAST::accept0(ASTVisitor *visitor)
+{
+ if (visitor->visit(this)) {
+ // visit ObjCProtocolDefinitionAST
+ for (SpecifierAST *it = attributes; it; it = it->next)
+ accept(it, visitor);
+ accept(protocol_refs, visitor);
+ // visit DeclarationAST
+ }
+ visitor->endVisit(this);
+}
+
+void ObjCProtocolRefsAST::accept0(ASTVisitor *visitor)
+{
+ if (visitor->visit(this)) {
+ // visit ObjCProtocolRefsAST
+ for (IdentifierListAST *it = identifier_list; it; it = it->next)
+ accept(it, visitor);
+ // visit AST
+ }
+ visitor->endVisit(this);
+}
+
+void ObjCMessageExpressionAST::accept0(ASTVisitor *visitor)
+{
+ if (visitor->visit(this)) {
+ // FIXME: TODO
+ }
+ visitor->endVisit(this);
+}
+
CPLUSPLUS_END_NAMESPACE
diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h
index caa93e5e1b..fd8c21971f 100644
--- a/src/shared/cplusplus/ASTVisitor.h
+++ b/src/shared/cplusplus/ASTVisitor.h
@@ -198,6 +198,12 @@ public:
// ObjC++
virtual bool visit(IdentifierListAST *) { return true; }
virtual bool visit(ObjCClassDeclarationAST *) { return true; }
+ virtual bool visit(ObjCClassInterfaceDeclarationAST *) { return true; }
+ virtual bool visit(ObjCCategoryInterfaceDeclarationAST *) { return true; }
+ virtual bool visit(ObjCProtocolDeclarationAST *) { return true; }
+ virtual bool visit(ObjCProtocolDefinitionAST *) { return true; }
+ virtual bool visit(ObjCProtocolRefsAST *) { return true; }
+ virtual bool visit(ObjCMessageExpressionAST *) { return true; }
virtual bool visit(DeclarationListAST *) { return true; }
virtual void endVisit(DeclarationListAST *) { }
@@ -307,6 +313,12 @@ public:
// ObjC++
virtual void endVisit(IdentifierListAST *) { }
virtual void endVisit(ObjCClassDeclarationAST *) { }
+ virtual void endVisit(ObjCClassInterfaceDeclarationAST *) { }
+ virtual void endVisit(ObjCCategoryInterfaceDeclarationAST *) { }
+ virtual void endVisit(ObjCProtocolDeclarationAST *) { }
+ virtual void endVisit(ObjCProtocolDefinitionAST *) { }
+ virtual void endVisit(ObjCProtocolRefsAST *) { }
+ virtual void endVisit(ObjCMessageExpressionAST *) { }
private:
Control *_control;
diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h
index ee5f8e876f..a4662226fa 100644
--- a/src/shared/cplusplus/ASTfwd.h
+++ b/src/shared/cplusplus/ASTfwd.h
@@ -171,6 +171,12 @@ class QtMethodAST;
// ObjC++
class IdentifierListAST;
class ObjCClassDeclarationAST;
+class ObjCProtocolDeclarationAST;
+class ObjCProtocolDefinitionAST;
+class ObjCClassInterfaceDeclarationAST;
+class ObjCCategoryInterfaceDeclarationAST;
+class ObjCProtocolRefsAST;
+class ObjCMessageExpressionAST;
CPLUSPLUS_END_NAMESPACE
CPLUSPLUS_END_HEADER
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index a005f7250b..c3faca243f 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -2890,18 +2890,19 @@ bool Parser::parseObjCSelectorExpression(ExpressionAST *&)
return true;
}
-bool Parser::parseObjCMessageExpression(ExpressionAST *&)
+bool Parser::parseObjCMessageExpression(ExpressionAST *&node)
{
if (LA() != T_LBRACKET)
return false;
- /*unsigned lbracket_token = */ consumeToken();
+ ObjCMessageExpressionAST *ast = new (_pool) ObjCMessageExpressionAST;
+ ast->lbracket_token = consumeToken();
parseObjCMessageReceiver();
parseObjCMessageArguments();
- unsigned rbracket_token = 0;
- match(T_RBRACKET, &rbracket_token);
+ match(T_RBRACKET, &(ast->rbracket_token));
+ node = ast;
return true;
}
@@ -3838,21 +3839,33 @@ bool Parser::lookAtObjCSelector() const
// objc-class-declaraton ::= T_AT_CLASS (T_IDENTIFIER @ T_COMMA) T_SEMICOLON
//
-bool Parser::parseObjCClassDeclaration(DeclarationAST *&)
+bool Parser::parseObjCClassDeclaration(DeclarationAST *&node)
{
if (LA() != T_AT_CLASS)
return false;
- /*unsigned objc_class_token = */ consumeToken();
+ ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST;
+
+ ast->class_token = consumeToken();
unsigned identifier_token = 0;
match(T_IDENTIFIER, &identifier_token);
+
+ ast->identifier_list = new (_pool) IdentifierListAST;
+ ast->identifier_list->identifier_token = identifier_token;
+ IdentifierListAST **nextId = &(ast->identifier_list->next);
+
while (LA() == T_COMMA) {
- consumeToken(); // skip T_COMMA
+ unsigned comma_token = consumeToken();
match(T_IDENTIFIER, &identifier_token);
+
+ *nextId = new (_pool) IdentifierListAST;
+ (*nextId)->comma_token = comma_token;
+ (*nextId)->identifier_token = identifier_token;
+ nextId = &((*nextId)->next);
}
- unsigned semicolon_token = 0;
- match(T_SEMICOLON, &semicolon_token);
+ match(T_SEMICOLON, &(ast->semicolon_token));
+ node = ast;
return true;
}
@@ -3871,7 +3884,7 @@ bool Parser::parseObjCClassDeclaration(DeclarationAST *&)
// objc-interface-declaration-list
// T_AT_END
//
-bool Parser::parseObjCInterface(DeclarationAST *&,
+bool Parser::parseObjCInterface(DeclarationAST *&node,
SpecifierAST *attributes)
{
if (! attributes && LA() == T___ATTRIBUTE__) {
@@ -3883,7 +3896,7 @@ bool Parser::parseObjCInterface(DeclarationAST *&,
if (LA() != T_AT_INTERFACE)
return false;
- /*unsigned objc_interface_token = */ consumeToken();
+ unsigned objc_interface_token = consumeToken();
unsigned identifier_token = 0;
match(T_IDENTIFIER, &identifier_token);
@@ -3894,40 +3907,49 @@ bool Parser::parseObjCInterface(DeclarationAST *&,
_translationUnit->error(attributes->firstToken(),
"invalid attributes for category interface declaration");
- unsigned lparen_token = 0, rparen_token = 0;
- match(T_LPAREN, &lparen_token);
+ ObjCCategoryInterfaceDeclarationAST *ast = new (_pool) ObjCCategoryInterfaceDeclarationAST;
+ // XXX: Should the attributes get stored anyway? (for fixing/refactoring purposes maybe...)
+ ast->interface_token = objc_interface_token;
+ ast->class_identifier_token = identifier_token;
+
+ match(T_LPAREN, &(ast->lparen_token));
if (LA() == T_IDENTIFIER)
- consumeToken();
+ ast->category_identifier_token = consumeToken();
- match(T_RPAREN, &rparen_token);
+ match(T_RPAREN, &(ast->rparen_token));
- parseObjCProtocolRefs();
+ parseObjCProtocolRefs(ast->protocol_refs);
while (parseObjCInterfaceMemberDeclaration()) {
}
- unsigned objc_end_token = 0;
- match(T_AT_END, &objc_end_token);
+ match(T_AT_END, &(ast->end_token));
+
+ node = ast;
return true;
- }
+ } else {
+ // a class interface declaration
+ ObjCClassInterfaceDeclarationAST *ast = new (_pool) ObjCClassInterfaceDeclarationAST;
+ ast->attributes = attributes;
+ ast->interface_token = objc_interface_token;
+ ast->class_identifier_token = identifier_token;
- // a class interface declaration
- if (LA() == T_COLON) {
- consumeToken();
- unsigned identifier_token = 0;
- match(T_IDENTIFIER, &identifier_token);
- }
+ if (LA() == T_COLON) {
+ ast->colon_token = consumeToken();
+ match(T_IDENTIFIER, &(ast->superclass_identifier_token));
+ }
- parseObjCProtocolRefs();
- parseObjClassInstanceVariables();
- while (parseObjCInterfaceMemberDeclaration()) {
+ parseObjCProtocolRefs(ast->protocol_refs);
+ parseObjClassInstanceVariables();
+ while (parseObjCInterfaceMemberDeclaration()) {
+ }
+ match(T_AT_END, &(ast->end_token));
+ node = ast;
+ return true;
}
- unsigned objc_end_token = 0;
- match(T_AT_END, &objc_end_token);
- return true;
}
// objc-protocol ::= T_AT_PROTOCOL (T_IDENTIFIER @ T_COMMA) T_SEMICOLON
//
-bool Parser::parseObjCProtocol(DeclarationAST *&,
+bool Parser::parseObjCProtocol(DeclarationAST *&node,
SpecifierAST *attributes)
{
if (! attributes && LA() == T___ATTRIBUTE__) {
@@ -3939,32 +3961,50 @@ bool Parser::parseObjCProtocol(DeclarationAST *&,
if (LA() != T_AT_PROTOCOL)
return false;
- /*unsigned objc_protocol_token = */ consumeToken();
+ unsigned protocol_token = consumeToken();
unsigned identifier_token = 0;
match(T_IDENTIFIER, &identifier_token);
if (LA() == T_COMMA || LA() == T_SEMICOLON) {
// a protocol forward declaration
+ ObjCProtocolDeclarationAST *ast = new (_pool) ObjCProtocolDeclarationAST;
+ ast->attributes = attributes;
+ ast->protocol_token = protocol_token;
+ ast->identifier_list = new (_pool) IdentifierListAST;
+ ast->identifier_list->identifier_token = identifier_token;
+ IdentifierListAST **nextId = &(ast->identifier_list->next);
+
while (LA() == T_COMMA) {
- consumeToken();
+ unsigned comma_token = consumeToken();
match(T_IDENTIFIER, &identifier_token);
+
+ *nextId = new (_pool) IdentifierListAST;
+ (*nextId)->comma_token = comma_token;
+ (*nextId)->identifier_token = identifier_token;
+ nextId = &((*nextId)->next);
}
- unsigned semicolon_token = 0;
- match(T_SEMICOLON, &semicolon_token);
+
+ match(T_SEMICOLON, &ast->semicolon_token);
+ node = ast;
return true;
- }
+ } else {
+ // a protocol definition
+ ObjCProtocolDefinitionAST *ast = new (_pool) ObjCProtocolDefinitionAST;
+ ast->attributes = attributes;
+ ast->protocol_token = protocol_token;
+ ast->identifier_token = identifier_token;
- // a protocol definition
- parseObjCProtocolRefs();
+ parseObjCProtocolRefs(ast->protocol_refs);
- while (parseObjCInterfaceMemberDeclaration()) {
- }
+ while (parseObjCInterfaceMemberDeclaration()) {
+ }
- unsigned objc_end_token = 0;
- match(T_AT_END, &objc_end_token);
+ match(T_AT_END, &(ast->end_token));
- return true;
+ node = ast;
+ return true;
+ }
}
// objc-implementation ::= T_AT_IMPLEMENTAION T_IDENTIFIER (T_COLON T_IDENTIFIER)?
@@ -4057,19 +4097,33 @@ bool Parser::parseObjCMethodDefinition()
// objc-protocol-refs ::= T_LESS (T_IDENTIFIER @ T_COMMA) T_GREATER
//
-bool Parser::parseObjCProtocolRefs()
+bool Parser::parseObjCProtocolRefs(ObjCProtocolRefsAST *&node)
{
if (LA() != T_LESS)
return false;
- unsigned less_token = 0, greater_token = 0;
+
+ ObjCProtocolRefsAST *ast = new (_pool) ObjCProtocolRefsAST;
+
+ match(T_LESS, &(ast->less_token));
+
unsigned identifier_token = 0;
- match(T_LESS, &less_token);
match(T_IDENTIFIER, &identifier_token);
+ ast->identifier_list = new (_pool) IdentifierListAST;
+ ast->identifier_list->identifier_token = identifier_token;
+ IdentifierListAST **nextId = &(ast->identifier_list->next);
+
while (LA() == T_COMMA) {
- consumeToken();
+ unsigned comma_token = consumeToken();
match(T_IDENTIFIER, &identifier_token);
+
+ *nextId = new (_pool) IdentifierListAST;
+ (*nextId)->comma_token = comma_token;
+ (*nextId)->identifier_token = identifier_token;
+ nextId = &((*nextId)->next);
}
- match(T_GREATER, &greater_token);
+
+ match(T_GREATER, &(ast->greater_token));
+ node = ast;
return true;
}
diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h
index c5515b05ec..8d02e42955 100644
--- a/src/shared/cplusplus/Parser.h
+++ b/src/shared/cplusplus/Parser.h
@@ -231,7 +231,7 @@ public:
bool parseObjCMethodDefinitionList();
bool parseObjCMethodDefinition();
- bool parseObjCProtocolRefs();
+ bool parseObjCProtocolRefs(ObjCProtocolRefsAST *&node);
bool parseObjClassInstanceVariables();
bool parseObjCInterfaceMemberDeclaration();
bool parseObjCInstanceVariableDeclaration(DeclarationAST *&node);