diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp index dc6a50567751613fbad3f63d3dc0c2dec1bd757f..3da0dbf4646c07feb8d7067160bbcddfe7170bc0 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 d22735eeb145b23c01098a7d1e7ac67b450d8d39..2e56fc52645b83d1abcaa508553f1ff00296c8a6 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 2e446c89ef1274f4542c053d17aeb7e89b569e68..b8ceec183cab538f9a5debc587878c49cd1c9b09 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 1673577474f4a8793b613287f4e2d9e74de6fdc6..c556b21015ea6c9899776b61b8e03db7569f30cf 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 caa93e5e1b82572c87f90c818fb8a7a144bf1bdc..fd8c21971f3427c6e9fb467c33363ac1ebd083ed 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 ee5f8e876ffaf2b961439f959b7bb4667350c65c..a4662226fa5121395cdbd8b9a636119fc19568e3 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 a005f7250bbc7aa67c421cfd8bfa46145dfcb1fb..c3faca243fdd3b468abc570905f1525dfd7a3d89 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 c5515b05ec0107db849b94b9f154cbcccfe14c72..8d02e429555a35bb935db4fbb8f41dc42b3e4c53 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);