From c8f155c0fc2fd64f01d50f6c085dd811cfdae17e Mon Sep 17 00:00:00 2001 From: Erik Verbruggen <erik.verbruggen@nokia.com> Date: Wed, 15 Jul 2009 12:11:07 +0200 Subject: [PATCH] AST additions for ObjC send_msg. --- src/shared/cplusplus/AST.cpp | 44 +++++++++++++++++++++++++++++-- src/shared/cplusplus/AST.h | 42 ++++++++++++++++++++++++++++- src/shared/cplusplus/ASTClone.cpp | 20 +++++++++++++- src/shared/cplusplus/ASTVisit.cpp | 31 +++++++++++++++++++++- src/shared/cplusplus/ASTVisitor.h | 4 +++ src/shared/cplusplus/ASTfwd.h | 2 ++ src/shared/cplusplus/Parser.cpp | 11 ++++---- src/shared/cplusplus/Parser.h | 4 +-- 8 files changed, 145 insertions(+), 13 deletions(-) diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp index 3da0dbf4646..6a72e3b90a7 100644 --- a/src/shared/cplusplus/AST.cpp +++ b/src/shared/cplusplus/AST.cpp @@ -2057,11 +2057,51 @@ unsigned ObjCMessageExpressionAST::firstToken() const unsigned ObjCMessageExpressionAST::lastToken() const { - if (rbracket_token) return rbracket_token + 1; + if (rbracket_token) + return rbracket_token + 1; - // FIXME: TODO + if (receiver_expression) + return receiver_expression->lastToken(); + + if (argument_list) + return argument_list->lastToken(); return lbracket_token + 1; } +unsigned ObjCMessageArgumentListAST::firstToken() const +{ + if (arg) + return arg->firstToken(); + // ### assert? + return 0; +} + +unsigned ObjCMessageArgumentListAST::lastToken() const +{ + for (const ObjCMessageArgumentListAST *it = this; it; it = it->next) { + if (! it->next && it->arg) { + return it->arg->lastToken(); + } + } + // ### assert? + return 0; +} + +unsigned ObjCMessageArgumentAST::firstToken() const +{ + return parameter_key_identifier; +} + +unsigned ObjCMessageArgumentAST::lastToken() const +{ + if (parameter_value_expression) + return parameter_value_expression->lastToken(); + + if (colon_token) + return colon_token + 1; + + return parameter_key_identifier + 1; +} + CPLUSPLUS_END_NAMESPACE diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h index 2e56fc52645..393126c9d47 100644 --- a/src/shared/cplusplus/AST.h +++ b/src/shared/cplusplus/AST.h @@ -2593,11 +2593,51 @@ protected: virtual void accept0(ASTVisitor *visitor); }; +class CPLUSPLUS_EXPORT ObjCMessageArgumentAST: public AST +{ +public: + unsigned parameter_key_identifier; + unsigned colon_token; + ExpressionAST *parameter_value_expression; + +public: + virtual ObjCMessageArgumentAST *asObjCMessageArgument() + { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual ObjCMessageArgumentAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); +}; + +class CPLUSPLUS_EXPORT ObjCMessageArgumentListAST: public AST +{ +public: + ObjCMessageArgumentAST *arg; + ObjCMessageArgumentListAST *next; + +public: + virtual ObjCMessageArgumentListAST *asObjCMessageArgumentList() + { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual ObjCMessageArgumentListAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); +}; + class CPLUSPLUS_EXPORT ObjCMessageExpressionAST: public ExpressionAST { public: unsigned lbracket_token; - // .. + ExpressionAST *receiver_expression; + ObjCMessageArgumentListAST *argument_list; unsigned rbracket_token; public: diff --git a/src/shared/cplusplus/ASTClone.cpp b/src/shared/cplusplus/ASTClone.cpp index b8ceec183ca..5065cfdd230 100644 --- a/src/shared/cplusplus/ASTClone.cpp +++ b/src/shared/cplusplus/ASTClone.cpp @@ -1288,9 +1288,27 @@ ObjCMessageExpressionAST *ObjCMessageExpressionAST::clone(MemoryPool *pool) cons { ObjCMessageExpressionAST *ast = new (pool) ObjCMessageExpressionAST; ast->lbracket_token = lbracket_token; - // FIXME: TODO + if (receiver_expression) ast->receiver_expression = receiver_expression->clone(pool); + if (argument_list) ast->argument_list = argument_list->clone(pool); ast->rbracket_token = rbracket_token; return ast; } +ObjCMessageArgumentListAST *ObjCMessageArgumentListAST::clone(MemoryPool *pool) const +{ + ObjCMessageArgumentListAST *ast = new (pool) ObjCMessageArgumentListAST; + if (arg) ast->arg = arg->clone(pool); + if (next) ast->next = next->clone(pool); + return ast; +} + +ObjCMessageArgumentAST *ObjCMessageArgumentAST::clone(MemoryPool *pool) const +{ + ObjCMessageArgumentAST *ast = new (pool) ObjCMessageArgumentAST; + ast->parameter_key_identifier = parameter_key_identifier; + ast->colon_token = colon_token; + if (parameter_value_expression) ast->parameter_value_expression = parameter_value_expression->clone(pool); + return ast; +} + CPLUSPLUS_END_NAMESPACE diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp index c556b21015e..0f2052127d8 100644 --- a/src/shared/cplusplus/ASTVisit.cpp +++ b/src/shared/cplusplus/ASTVisit.cpp @@ -1200,7 +1200,36 @@ void ObjCProtocolRefsAST::accept0(ASTVisitor *visitor) void ObjCMessageExpressionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // FIXME: TODO + // visit ObjCMessageExpressionAST + if (receiver_expression) + accept(receiver_expression, visitor); + if (argument_list) + accept(argument_list, visitor); + // visit ExpressionAST + } + visitor->endVisit(this); +} + +void ObjCMessageArgumentListAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + // visit ObjCMessageArgumentListAST + if (arg) + accept(arg, visitor); + if (next) + accept(next, visitor); + // visit AST + } + visitor->endVisit(this); +} + +void ObjCMessageArgumentAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + // visit ObjCMessageArgumentAST + if (parameter_value_expression) + accept(parameter_value_expression, visitor); + // visit AST } visitor->endVisit(this); } diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h index fd8c21971f3..4b0672cbc1d 100644 --- a/src/shared/cplusplus/ASTVisitor.h +++ b/src/shared/cplusplus/ASTVisitor.h @@ -204,6 +204,8 @@ public: virtual bool visit(ObjCProtocolDefinitionAST *) { return true; } virtual bool visit(ObjCProtocolRefsAST *) { return true; } virtual bool visit(ObjCMessageExpressionAST *) { return true; } + virtual bool visit(ObjCMessageArgumentListAST *) { return true; } + virtual bool visit(ObjCMessageArgumentAST *) { return true; } virtual bool visit(DeclarationListAST *) { return true; } virtual void endVisit(DeclarationListAST *) { } @@ -319,6 +321,8 @@ public: virtual void endVisit(ObjCProtocolDefinitionAST *) { } virtual void endVisit(ObjCProtocolRefsAST *) { } virtual void endVisit(ObjCMessageExpressionAST *) { } + virtual void endVisit(ObjCMessageArgumentListAST *) { } + virtual void endVisit(ObjCMessageArgumentAST *) { } private: Control *_control; diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h index a4662226fa5..e12393df6a8 100644 --- a/src/shared/cplusplus/ASTfwd.h +++ b/src/shared/cplusplus/ASTfwd.h @@ -177,6 +177,8 @@ class ObjCClassInterfaceDeclarationAST; class ObjCCategoryInterfaceDeclarationAST; class ObjCProtocolRefsAST; class ObjCMessageExpressionAST; +class ObjCMessageArgumentListAST; +class ObjCMessageArgumentAST; CPLUSPLUS_END_NAMESPACE CPLUSPLUS_END_HEADER diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp index 635c337ced4..cf091cfa0e0 100644 --- a/src/shared/cplusplus/Parser.cpp +++ b/src/shared/cplusplus/Parser.cpp @@ -2914,21 +2914,20 @@ bool Parser::parseObjCMessageExpression(ExpressionAST *&node) ObjCMessageExpressionAST *ast = new (_pool) ObjCMessageExpressionAST; ast->lbracket_token = consumeToken(); - parseObjCMessageReceiver(); - parseObjCMessageArguments(); + parseObjCMessageReceiver(ast->receiver_expression); + parseObjCMessageArguments(ast->argument_list); match(T_RBRACKET, &(ast->rbracket_token)); node = ast; return true; } -bool Parser::parseObjCMessageReceiver() +bool Parser::parseObjCMessageReceiver(ExpressionAST *&node) { - ExpressionAST *expression = 0; - return parseExpression(expression); + return parseExpression(node); } -bool Parser::parseObjCMessageArguments() +bool Parser::parseObjCMessageArguments(ObjCMessageArgumentListAST *& /*node*/) { if (LA() == T_RBRACKET) return false; // nothing to do. diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h index 8d02e429555..4d6af741bfd 100644 --- a/src/shared/cplusplus/Parser.h +++ b/src/shared/cplusplus/Parser.h @@ -225,8 +225,8 @@ public: bool parseObjCStringLiteral(ExpressionAST *&node); bool parseObjCMethodSignature(); bool parseObjCMessageExpression(ExpressionAST *&node); - bool parseObjCMessageReceiver(); - bool parseObjCMessageArguments(); + bool parseObjCMessageReceiver(ExpressionAST *&node); + bool parseObjCMessageArguments(ObjCMessageArgumentListAST *&node); bool parseObjCSelectorArgs(); bool parseObjCMethodDefinitionList(); bool parseObjCMethodDefinition(); -- GitLab