diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp index 08fcb2fa9d0912643ce54c438933d49c6df47993..51a3c1ac34899523dc50593dd570c0f4abe65c1c 100644 --- a/src/shared/cplusplus/AST.cpp +++ b/src/shared/cplusplus/AST.cpp @@ -2258,4 +2258,62 @@ unsigned ObjCPropertyDeclarationAST::lastToken() const return property_token + 1; } +unsigned ObjCMessageArgumentDeclarationAST::firstToken() const +{ + return param_selector_token; +} + +unsigned ObjCMessageArgumentDeclarationAST::lastToken() const +{ + if (param_name_token) + return param_name_token + 1; + else if (colon_token) + return colon_token + 1; + else if (type_name) + return type_name->lastToken(); + else if (attributes) + return attributes->lastToken(); + else + return param_name_token + 1; +} + +unsigned ObjCMessageArgumentDeclarationListAST::firstToken() const +{ + if (argument_declaration) + return argument_declaration->firstToken(); + else if (next) + return next->firstToken(); + else + // ### Assert? + return 0; +} + +unsigned ObjCMessageArgumentDeclarationListAST::lastToken() const +{ + for (const ObjCMessageArgumentDeclarationListAST *it = this; it; it = it->next) { + if (! it->next && it->argument_declaration) { + return it->argument_declaration->lastToken(); + } + } + // ### assert? + return 0; +} + +unsigned ObjCMethodPrototypeAST::firstToken() const +{ + return method_type_token; +} + +unsigned ObjCMethodPrototypeAST::lastToken() const +{ + if (attributes) + return attributes->lastToken(); + else if (arguments) + return arguments->lastToken(); + else if (type_name) + return type_name->lastToken(); + else + return method_type_token + 1; +} + CPLUSPLUS_END_NAMESPACE diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h index 6fef4cafef415c241f2e67f8ebf5e5282a155f52..898fd16c87df3c8c771e2cba744fb7190fb2bf11 100644 --- a/src/shared/cplusplus/AST.h +++ b/src/shared/cplusplus/AST.h @@ -2820,6 +2820,68 @@ protected: virtual void accept0(ASTVisitor *visitor); }; +class CPLUSPLUS_EXPORT ObjCMessageArgumentDeclarationAST: public AST +{ +public: + unsigned param_selector_token; + unsigned colon_token; + ObjCTypeNameAST* type_name; + SpecifierAST *attributes; + unsigned param_name_token; + +public: + virtual ObjCMessageArgumentDeclarationAST *asObjCMessageArgumentDeclaration() + { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual ObjCMessageArgumentDeclarationAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); +}; + +class CPLUSPLUS_EXPORT ObjCMessageArgumentDeclarationListAST: public AST +{ +public: + ObjCMessageArgumentDeclarationAST *argument_declaration; + ObjCMessageArgumentDeclarationListAST *next; + +public: + virtual ObjCMessageArgumentDeclarationListAST *asObjCMessageArgumentDeclarationList() + { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual ObjCMessageArgumentDeclarationListAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); +}; + +class CPLUSPLUS_EXPORT ObjCMethodPrototypeAST: public DeclarationAST +{ +public: + unsigned method_type_token; + ObjCTypeNameAST *type_name; + ObjCMessageArgumentDeclarationListAST *arguments; + SpecifierAST *attributes; + +public: + virtual ObjCMethodPrototypeAST *asObjCMethodPrototype() + { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual ObjCMethodPrototypeAST *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 2a95a1c0f347e3a06b8c71ac7d77ac598bc2d923..385958d47c6a11441f07427afe356e78b86912ff 100644 --- a/src/shared/cplusplus/ASTClone.cpp +++ b/src/shared/cplusplus/ASTClone.cpp @@ -1390,4 +1390,33 @@ ObjCPropertyDeclarationAST *ObjCPropertyDeclarationAST::clone(MemoryPool *pool) return ast; } +ObjCMessageArgumentDeclarationAST *ObjCMessageArgumentDeclarationAST::clone(MemoryPool *pool) const +{ + ObjCMessageArgumentDeclarationAST *ast = new (pool) ObjCMessageArgumentDeclarationAST; + ast->param_selector_token = param_selector_token; + ast->colon_token = colon_token; + if (type_name) ast->type_name = type_name->clone(pool); + if (attributes) ast->attributes = attributes->clone(pool); + ast->param_name_token = param_name_token; + return ast; +} + +ObjCMessageArgumentDeclarationListAST *ObjCMessageArgumentDeclarationListAST::clone(MemoryPool *pool) const +{ + ObjCMessageArgumentDeclarationListAST *ast = new (pool) ObjCMessageArgumentDeclarationListAST; + if (argument_declaration) ast->argument_declaration = argument_declaration->clone(pool); + if (next) ast->next = next->clone(pool); + return ast; +} + +ObjCMethodPrototypeAST *ObjCMethodPrototypeAST::clone(MemoryPool *pool) const +{ + ObjCMethodPrototypeAST *ast = new (pool) ObjCMethodPrototypeAST; + ast->method_type_token = method_type_token; + if (type_name) ast->type_name = type_name->clone(pool); + if (arguments) ast->arguments = arguments->clone(pool); + if (attributes) ast->attributes = attributes->clone(pool); + return ast; +} + CPLUSPLUS_END_NAMESPACE diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp index d5238f52a63aa3f0af5e3ee8bc2ad16a121d97cf..b6b21ad357191a57f5a69fad1a5523b3cf8c67f5 100644 --- a/src/shared/cplusplus/ASTVisit.cpp +++ b/src/shared/cplusplus/ASTVisit.cpp @@ -1309,8 +1309,6 @@ void ObjcPropertyAttributeListAST::accept0(ASTVisitor *visitor) // visit ObjcPropertyAttributeListAST if (attr) accept(attr, visitor); - if (next) - accept(next, visitor); // visit AST } visitor->endVisit(this); @@ -1320,8 +1318,8 @@ void ObjCPropertyDeclarationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { // visit ObjCPropertyDeclarationAST: - if (property_attributes) - accept(property_attributes, visitor); + for (ObjcPropertyAttributeListAST *it = property_attributes; it; it = it->next) + accept(it, visitor); if (simple_declaration) accept(simple_declaration, visitor); // visit DeclarationAST: @@ -1329,4 +1327,43 @@ void ObjCPropertyDeclarationAST::accept0(ASTVisitor *visitor) visitor->endVisit(this); } +void ObjCMessageArgumentDeclarationAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + // visit ObjCMessageArgumentDeclarationAST + if (type_name) + accept(type_name, visitor); + if (attributes) + accept(attributes, visitor); + // visit AST + } + visitor->endVisit(this); +} + +void ObjCMessageArgumentDeclarationListAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + // visit ObjCMessageArgumentDeclarationListAST + if (argument_declaration) + accept(argument_declaration, visitor); + // visit AST + } + visitor->endVisit(this); +} + +void ObjCMethodPrototypeAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + // visit ObjCMethodPrototypeAST + if (type_name) + accept(type_name, visitor); + for (ObjCMessageArgumentDeclarationListAST *it = arguments; it; it = it->next) + accept(it, visitor); + if (attributes) + accept(attributes, visitor); + // visit AST + } + visitor->endVisit(this); +} + CPLUSPLUS_END_NAMESPACE diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h index 0e056324c22d5d77a601662a54b3a1bb2c0edaa7..b272c7077a9bc15ce275cf39ad9ba0befcc9eeba 100644 --- a/src/shared/cplusplus/ASTVisitor.h +++ b/src/shared/cplusplus/ASTVisitor.h @@ -214,6 +214,9 @@ public: virtual bool visit(ObjcPropertyAttributeAST *) { return true; } virtual bool visit(ObjcPropertyAttributeListAST *) { return true; } virtual bool visit(ObjCPropertyDeclarationAST *) { return true; } + virtual bool visit(ObjCMethodPrototypeAST *) { return true; } + virtual bool visit(ObjCMessageArgumentDeclarationListAST *) { return true; } + virtual bool visit(ObjCMessageArgumentDeclarationAST *) { return true; } virtual bool visit(DeclarationListAST *) { return true; } virtual void endVisit(DeclarationListAST *) { } @@ -339,6 +342,9 @@ public: virtual void endVisit(ObjcPropertyAttributeAST *) { } virtual void endVisit(ObjcPropertyAttributeListAST *) { } virtual void endVisit(ObjCPropertyDeclarationAST *) { } + virtual void endVisit(ObjCMethodPrototypeAST *) { } + virtual void endVisit(ObjCMessageArgumentDeclarationListAST *) { } + virtual void endVisit(ObjCMessageArgumentDeclarationAST *) { } private: Control *_control; diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h index 91564058e215315a7627eefffe74898bfd758b93..f123e736897b5a170cb65b93200f31464780cbdf 100644 --- a/src/shared/cplusplus/ASTfwd.h +++ b/src/shared/cplusplus/ASTfwd.h @@ -187,6 +187,9 @@ class ObjCVisibilityDeclarationAST; class ObjCPropertyDeclarationAST; class ObjcPropertyAttributeListAST; class ObjcPropertyAttributeAST; +class ObjCMethodPrototypeAST; +class ObjCMessageArgumentDeclarationListAST; +class ObjCMessageArgumentDeclarationAST; CPLUSPLUS_END_NAMESPACE CPLUSPLUS_END_HEADER diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp index 09271cc773617aab25aa1cf1d6e4233b98a7d7ec..b75c10d9ddca4e63e769543d202dd80e5b04f813 100644 --- a/src/shared/cplusplus/Parser.cpp +++ b/src/shared/cplusplus/Parser.cpp @@ -4195,7 +4195,8 @@ bool Parser::parseObjCMethodDefinitionList() bool Parser::parseObjCMethodDefinition() { - if (! parseObjCMethodPrototype()) + DeclarationAST *ast = 0; + if (! parseObjCMethodPrototype(ast)) return false; if (LA() == T_SEMICOLON) @@ -4298,7 +4299,7 @@ bool Parser::parseObjCInterfaceMemberDeclaration(DeclarationAST *&node) case T_PLUS: case T_MINUS: - return parseObjCMethodPrototype(); + return parseObjCMethodPrototype(node); case T_ENUM: case T_CLASS: @@ -4377,22 +4378,31 @@ bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&node, SpecifierAST *) // 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 Parser::parseObjCMethodPrototype(DeclarationAST *&node) { if (LA() != T_PLUS && LA() != T_MINUS) return false; - /*unsigned method_type_token = */ consumeToken(); + ObjCMethodPrototypeAST *ast = new (_pool) ObjCMethodPrototypeAST; + ast->method_type_token = consumeToken(); - ObjCTypeNameAST *type_name = 0; - parseObjCTypeName(type_name); - - unsigned selector_token = 0; + parseObjCTypeName(ast->type_name); if ((lookAtObjCSelector() && LA(2) == T_COLON) || LA() == T_COLON) { - while (parseObjCKeywordDeclaration()) { + ObjCMessageArgumentDeclarationAST *declaration = 0; + parseObjCKeywordDeclaration(declaration); + + ast->arguments = new (_pool) ObjCMessageArgumentDeclarationListAST; + ast->arguments->argument_declaration = declaration; + ObjCMessageArgumentDeclarationListAST **last = &(ast->arguments); + + while (parseObjCKeywordDeclaration(declaration)) { + (*last)->next = new (_pool) ObjCMessageArgumentDeclarationListAST; + last = &((*last)->next); + (*last)->argument_declaration = declaration; } + // TODO: err, what does this parse? while (LA() == T_COMMA) { consumeToken(); @@ -4405,15 +4415,18 @@ bool Parser::parseObjCMethodPrototype() parseParameterDeclaration(parameter_declaration); } } else if (lookAtObjCSelector()) { - parseObjCSelector(selector_token); + ast->arguments = new (_pool) ObjCMessageArgumentDeclarationListAST; + ast->arguments->argument_declaration = new (_pool) ObjCMessageArgumentDeclarationAST; + parseObjCSelector(ast->arguments->argument_declaration->param_selector_token); } else { _translationUnit->error(cursor(), "expected a selector"); } - SpecifierAST *attributes = 0, **attr = &attributes; + SpecifierAST **attr = &(ast->attributes); while (parseAttributeSpecifier(*attr)) attr = &(*attr)->next; + node = ast; return true; } @@ -4471,27 +4484,24 @@ bool Parser::parseObjCSelector(unsigned &selector_token) // objc-keyword-decl ::= objc-selector? T_COLON objc-type-name? objc-keyword-attributes-opt T_IDENTIFIER // -bool Parser::parseObjCKeywordDeclaration() +bool Parser::parseObjCKeywordDeclaration(ObjCMessageArgumentDeclarationAST *&node) { if (! (LA() == T_COLON || (lookAtObjCSelector() && LA(2) == T_COLON))) return false; - unsigned selector_token = 0; - parseObjCSelector(selector_token); - - unsigned colon_token = 0; - match(T_COLON, &colon_token); + ObjCMessageArgumentDeclarationAST *ast = new (_pool) ObjCMessageArgumentDeclarationAST; - ObjCTypeNameAST *type_name = 0; - parseObjCTypeName(type_name); + parseObjCSelector(ast->param_selector_token); + match(T_COLON, &(ast->colon_token)); + parseObjCTypeName(ast->type_name); - SpecifierAST *attributes = 0, **attr = &attributes; + SpecifierAST **attr = &(ast->attributes); while (parseAttributeSpecifier(*attr)) attr = &(*attr)->next; - unsigned identifier_token = 0; - match(T_IDENTIFIER, &identifier_token); + match(T_IDENTIFIER, &(ast->param_name_token)); + node = ast; return true; } diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h index d292c5b935138f603f76f00a1605a014f61b2698..d29749834442873802825806d6d115c7a8e8c3bc 100644 --- a/src/shared/cplusplus/Parser.h +++ b/src/shared/cplusplus/Parser.h @@ -238,11 +238,11 @@ public: bool parseObjCPropertyDeclaration(DeclarationAST *&node, SpecifierAST *attributes = 0); bool parseObjCImplementation(DeclarationAST *&node); - bool parseObjCMethodPrototype(); + bool parseObjCMethodPrototype(DeclarationAST *&node); bool parseObjCPropertyAttribute(ObjcPropertyAttributeAST *&node); bool parseObjCTypeName(ObjCTypeNameAST *&node); bool parseObjCSelector(unsigned &selector_token); - bool parseObjCKeywordDeclaration(); + bool parseObjCKeywordDeclaration(ObjCMessageArgumentDeclarationAST *&node); bool parseObjCTypeQualifiers(unsigned &type_qualifier); bool parseObjCEnd(DeclarationAST *&node);