diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp index e8ecfa07cdba7fbcd5948c1d94ee04d05ed4d0c2..0eae1bd0fed9e8369a0386251e108964d02bc30c 100644 --- a/src/shared/cplusplus/AST.cpp +++ b/src/shared/cplusplus/AST.cpp @@ -1997,7 +1997,10 @@ unsigned ObjCClassInterfaceDeclarationAST::lastToken() const unsigned ObjCCategoryInterfaceDeclarationAST::firstToken() const { - return interface_token; + if (attributes) + return attributes->firstToken(); + else + return interface_token; } unsigned ObjCCategoryInterfaceDeclarationAST::lastToken() const @@ -2319,6 +2322,32 @@ unsigned ObjCMethodPrototypeAST::lastToken() const return method_type_token + 1; } +unsigned ObjCMethodDeclarationAST::firstToken() const +{ + return method_prototype->firstToken(); +} + +unsigned ObjCMethodDeclarationAST::lastToken() const +{ + if (semicolon_token) + return semicolon_token + 1; + else + return method_prototype->lastToken(); +} + +unsigned ObjCMethodDefinitionAST::firstToken() const +{ + return method_prototype->firstToken(); +} + +unsigned ObjCMethodDefinitionAST::lastToken() const +{ + if (function_body) + return function_body->lastToken(); + else + return method_prototype->lastToken(); +} + unsigned ObjCClassImplementationAST::firstToken() const { return implementation_token; diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h index f6ab2626eb6c6a3d8a24497f255541d7cbfdd694..cbbbc5da69f72ea1eb772a76ed2f6a4c63a3b737 100644 --- a/src/shared/cplusplus/AST.h +++ b/src/shared/cplusplus/AST.h @@ -2511,6 +2511,7 @@ protected: class CPLUSPLUS_EXPORT ObjCCategoryInterfaceDeclarationAST: public DeclarationAST { public: + SpecifierAST *attributes; unsigned interface_token; unsigned class_identifier_token; unsigned lparen_token; @@ -2862,7 +2863,7 @@ protected: virtual void accept0(ASTVisitor *visitor); }; -class CPLUSPLUS_EXPORT ObjCMethodPrototypeAST: public DeclarationAST +class CPLUSPLUS_EXPORT ObjCMethodPrototypeAST: public AST { public: unsigned method_type_token; @@ -2883,6 +2884,44 @@ protected: virtual void accept0(ASTVisitor *visitor); }; +class CPLUSPLUS_EXPORT ObjCMethodDeclarationAST: public DeclarationAST +{ +public: + ObjCMethodPrototypeAST *method_prototype; + unsigned semicolon_token; + +public: + virtual ObjCMethodDeclarationAST *asObjCMethodDeclaration() + { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual ObjCMethodDeclarationAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); +}; + +class CPLUSPLUS_EXPORT ObjCMethodDefinitionAST: public DeclarationAST +{ +public: + ObjCMethodPrototypeAST *method_prototype; + StatementAST *function_body; + +public: + virtual ObjCMethodDefinitionAST *asObjCMethodDefinition() + { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual ObjCMethodDefinitionAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); +}; + class CPLUSPLUS_EXPORT ObjCClassImplementationAST: public DeclarationAST { public: diff --git a/src/shared/cplusplus/ASTClone.cpp b/src/shared/cplusplus/ASTClone.cpp index 1e160ae2747a583c0824fd92e6d39c7a036adda5..3340a39f25cf837e1d0f778e9caf059192e94010 100644 --- a/src/shared/cplusplus/ASTClone.cpp +++ b/src/shared/cplusplus/ASTClone.cpp @@ -1246,6 +1246,7 @@ ObjCCategoryInterfaceDeclarationAST *ObjCCategoryInterfaceDeclarationAST::clone( ObjCCategoryInterfaceDeclarationAST *ast = new (pool) ObjCCategoryInterfaceDeclarationAST; // copy DeclarationAST // copy ObjCCategoryInterfaceDeclarationAST + if (attributes) ast->attributes = attributes->clone(pool); ast->interface_token = interface_token; ast->class_identifier_token = class_identifier_token; if (protocol_refs) ast->protocol_refs = protocol_refs->clone(pool); @@ -1420,6 +1421,22 @@ ObjCMethodPrototypeAST *ObjCMethodPrototypeAST::clone(MemoryPool *pool) const return ast; } +ObjCMethodDeclarationAST *ObjCMethodDeclarationAST::clone(MemoryPool *pool) const +{ + ObjCMethodDeclarationAST *ast = new (pool) ObjCMethodDeclarationAST; + if (method_prototype) ast->method_prototype = method_prototype->clone(pool); + ast->semicolon_token = semicolon_token; + return ast; +} + +ObjCMethodDefinitionAST *ObjCMethodDefinitionAST::clone(MemoryPool *pool) const +{ + ObjCMethodDefinitionAST *ast = new (pool) ObjCMethodDefinitionAST; + if (method_prototype) ast->method_prototype = method_prototype->clone(pool); + if (function_body) ast->function_body = function_body->clone(pool); + return ast; +} + ObjCClassImplementationAST *ObjCClassImplementationAST::clone(MemoryPool *pool) const { ObjCClassImplementationAST *ast = new (pool) ObjCClassImplementationAST; diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp index 98fe8a84adb4184788ad742edc701d58fa42c62a..9b43a34bfd7a9a8a8fade1a619221aabfc299ac7 100644 --- a/src/shared/cplusplus/ASTVisit.cpp +++ b/src/shared/cplusplus/ASTVisit.cpp @@ -1159,7 +1159,12 @@ void ObjCCategoryInterfaceDeclarationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { // visit ObjCCategoryInterfaceDeclarationAST - accept(protocol_refs, visitor); + if (attributes) + accept(attributes, visitor); + if (protocol_refs) + accept(protocol_refs, visitor); + if (member_declarations) + accept(member_declarations, visitor); // visit DeclarationAST } visitor->endVisit(this); @@ -1368,6 +1373,30 @@ void ObjCMethodPrototypeAST::accept0(ASTVisitor *visitor) visitor->endVisit(this); } +void ObjCMethodDeclarationAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + // visit ObjCMethodDeclarationAST + if (method_prototype) + accept(method_prototype, visitor); + // visit DeclarationAST + } + visitor->endVisit(this); +} + +void ObjCMethodDefinitionAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + // visit ObjCMethodDefinitionAST + if (method_prototype) + accept(method_prototype, visitor); + if (function_body) + accept(function_body, visitor); + // visit DeclarationAST + } + visitor->endVisit(this); +} + void ObjCClassImplementationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h index 5279d290f502916a4816eb484bf222b0a1b0e454..dc289fdcb5a5229ef11784962ba70755219239da 100644 --- a/src/shared/cplusplus/ASTVisitor.h +++ b/src/shared/cplusplus/ASTVisitor.h @@ -215,6 +215,8 @@ public: virtual bool visit(ObjcPropertyAttributeListAST *) { return true; } virtual bool visit(ObjCPropertyDeclarationAST *) { return true; } virtual bool visit(ObjCMethodPrototypeAST *) { return true; } + virtual bool visit(ObjCMethodDeclarationAST *) { return true; } + virtual bool visit(ObjCMethodDefinitionAST *) { return true; } virtual bool visit(ObjCMessageArgumentDeclarationListAST *) { return true; } virtual bool visit(ObjCMessageArgumentDeclarationAST *) { return true; } virtual bool visit(ObjCClassImplementationAST *) { return true; } @@ -350,6 +352,8 @@ public: virtual void endVisit(ObjcPropertyAttributeListAST *) { } virtual void endVisit(ObjCPropertyDeclarationAST *) { } virtual void endVisit(ObjCMethodPrototypeAST *) { } + virtual void endVisit(ObjCMethodDeclarationAST *) { } + virtual void endVisit(ObjCMethodDefinitionAST *) { } virtual void endVisit(ObjCMessageArgumentDeclarationListAST *) { } virtual void endVisit(ObjCMessageArgumentDeclarationAST *) { } virtual void endVisit(ObjCClassImplementationAST *) { } diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h index 5416856614c641251fa7b8681a45cd86de2e4788..a6ad8261756c015aee3cc116df0e7f638aa55ed5 100644 --- a/src/shared/cplusplus/ASTfwd.h +++ b/src/shared/cplusplus/ASTfwd.h @@ -188,6 +188,8 @@ class ObjCPropertyDeclarationAST; class ObjcPropertyAttributeListAST; class ObjcPropertyAttributeAST; class ObjCMethodPrototypeAST; +class ObjCMethodDeclarationAST; +class ObjCMethodDefinitionAST; class ObjCMessageArgumentDeclarationListAST; class ObjCMessageArgumentDeclarationAST; class ObjCCategoryImplementationAST; diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp index 2856e07622ad15cc683747676cd7dc8a32a8221c..616d2ed3e2ab985f265bc6d9d45795665ddba6cf 100644 --- a/src/shared/cplusplus/Parser.cpp +++ b/src/shared/cplusplus/Parser.cpp @@ -63,7 +63,6 @@ Parser::Parser(TranslationUnit *unit) : _translationUnit(unit), _control(_translationUnit->control()), _pool(_translationUnit->memoryPool()), - _objcInContextKeyword(_control->findOrInsertIdentifier("in")), _tokenIndex(1), _templateArguments(0), _qtMocRunEnabled(false), @@ -2178,16 +2177,19 @@ bool Parser::parseForStatement(StatementAST *&node) unsigned for_token = consumeToken(); unsigned lparen_token = 0; match(T_LPAREN, &lparen_token); + + // FIXME: for ObjC fast enumeration, this needs a semicolon before the "in" token, which is obviously wrong. StatementAST *initializer = 0; parseForInitStatement(initializer); + unsigned in_token = 0; - if (LA() == T_IDENTIFIER && tok().identifier == _objcInContextKeyword) { + if (parseObjCContextKeyword(Token_in, in_token)) { ObjCFastEnumerationAST *ast = new (_pool) ObjCFastEnumerationAST; ast->for_token = for_token; ast->lparen_token = lparen_token; ast->initializer = initializer; - ast->in_token = consumeToken(); + ast->in_token = in_token; parseExpression(ast->fast_enumeratable_expression); match(T_RPAREN, &ast->rparen_token); parseStatement(ast->body_statement); @@ -3978,7 +3980,7 @@ bool Parser::parseObjCInterface(DeclarationAST *&node, "invalid attributes for category interface declaration"); ObjCCategoryInterfaceDeclarationAST *ast = new (_pool) ObjCCategoryInterfaceDeclarationAST; - // TODO: Should the attributes get stored anyway? (for fixing/refactoring purposes maybe...) + ast->attributes = attributes; ast->interface_token = objc_interface_token; ast->class_identifier_token = identifier_token; @@ -4169,27 +4171,28 @@ bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node) case T_AT_SYNTHESIZE: { ObjCSynthesizedPropertiesDeclarationAST *ast = new (_pool) ObjCSynthesizedPropertiesDeclarationAST; ast->synthesized_token = consumeToken(); - // TODO EV - unsigned identifier_token = 0; - match(T_IDENTIFIER, &identifier_token); + ObjCSynthesizedPropertyListAST *last = new (_pool) ObjCSynthesizedPropertyListAST; + ast->property_identifiers = last; + last->synthesized_property = new (_pool) ObjCSynthesizedPropertyAST; + match(T_IDENTIFIER, &(last->synthesized_property->property_identifier)); if (LA() == T_EQUAL) { - consumeToken(); + last->synthesized_property->equals_token = consumeToken(); - unsigned aliassed_identifier_token = 0; - match(T_IDENTIFIER, &aliassed_identifier_token); + match(T_IDENTIFIER, &(last->synthesized_property->property_alias_identifier)); } while (LA() == T_COMMA) { - consumeToken(); + last->comma_token = consumeToken(); + last->next = new (_pool) ObjCSynthesizedPropertyListAST; + last = last->next; - match(T_IDENTIFIER, &identifier_token); + match(T_IDENTIFIER, &(last->synthesized_property->property_identifier)); if (LA() == T_EQUAL) { - consumeToken(); + last->synthesized_property->equals_token = consumeToken(); - unsigned aliassed_identifier_token = 0; - match(T_IDENTIFIER, &aliassed_identifier_token); + match(T_IDENTIFIER, &(last->synthesized_property->property_alias_identifier)); } } @@ -4246,16 +4249,24 @@ bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node) bool Parser::parseObjCMethodDefinition(DeclarationAST *&node) { - // TODO EV: - DeclarationAST *ast = 0; - if (! parseObjCMethodPrototype(ast)) + ObjCMethodPrototypeAST *method_prototype; + if (! parseObjCMethodPrototype(method_prototype)) return false; - if (LA() == T_SEMICOLON) - consumeToken(); + if (LA() == T_SEMICOLON) { + // method declaration: + ObjCMethodDeclarationAST *ast = new (_pool) ObjCMethodDeclarationAST; + ast->method_prototype = method_prototype; + ast->semicolon_token = consumeToken(); + node = ast; + } else { + // method definition: + ObjCMethodDefinitionAST *ast = new (_pool) ObjCMethodDefinitionAST; + ast->method_prototype = method_prototype; + parseFunctionBody(ast->function_body); + node = ast; + } - StatementAST *function_body = 0; - parseFunctionBody(function_body); return true; } @@ -4350,8 +4361,16 @@ bool Parser::parseObjCInterfaceMemberDeclaration(DeclarationAST *&node) } case T_PLUS: - case T_MINUS: - return parseObjCMethodPrototype(node); + case T_MINUS: { + ObjCMethodDeclarationAST *ast = new (_pool) ObjCMethodDeclarationAST; + if (parseObjCMethodPrototype(ast->method_prototype)) { + match(T_SEMICOLON, &(ast->semicolon_token)); + node = ast; + return true; + } else { + return false; + } + } case T_ENUM: case T_CLASS: @@ -4431,7 +4450,7 @@ bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&node, SpecifierAST *a // objc-method-decl ::= objc-type-name? objc-selector // objc-method-decl ::= objc-type-name? objc-keyword-decl-list objc-parmlist-opt // -bool Parser::parseObjCMethodPrototype(DeclarationAST *&node) +bool Parser::parseObjCMethodPrototype(ObjCMethodPrototypeAST *&node) { if (LA() != T_PLUS && LA() != T_MINUS) return false; @@ -4455,7 +4474,7 @@ bool Parser::parseObjCMethodPrototype(DeclarationAST *&node) (*last)->argument_declaration = declaration; } - // TODO: err, what does this parse? + // TODO EV: get this in the ast while (LA() == T_COMMA) { consumeToken(); @@ -4571,4 +4590,17 @@ bool Parser::parseObjCTypeQualifiers(unsigned &type_qualifier) return true; } +bool Parser::parseObjCContextKeyword(int kind, unsigned &in_token) +{ + if (LA() != T_IDENTIFIER) + return false; + + Identifier *id = tok().identifier; + const int k = classifyObjectiveCTypeQualifiers(id->chars(), id->size()); + if (k != kind) + return false; + in_token = consumeToken(); + return true; +} + CPLUSPLUS_END_NAMESPACE diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h index df017209e158c574b2913a38056bcd3a31dd1b6e..5fd5253e34804ea86b6da4a73a6144b5c1c9367b 100644 --- a/src/shared/cplusplus/Parser.h +++ b/src/shared/cplusplus/Parser.h @@ -238,12 +238,13 @@ public: bool parseObjCPropertyDeclaration(DeclarationAST *&node, SpecifierAST *attributes = 0); bool parseObjCImplementation(DeclarationAST *&node); - bool parseObjCMethodPrototype(DeclarationAST *&node); + bool parseObjCMethodPrototype(ObjCMethodPrototypeAST *&node); bool parseObjCPropertyAttribute(ObjcPropertyAttributeAST *&node); bool parseObjCTypeName(ObjCTypeNameAST *&node); bool parseObjCSelector(unsigned &selector_token); bool parseObjCKeywordDeclaration(ObjCMessageArgumentDeclarationAST *&node); bool parseObjCTypeQualifiers(unsigned &type_qualifier); + bool parseObjCContextKeyword(int kind, unsigned &in_token); bool lookAtObjCSelector() const; @@ -287,7 +288,6 @@ private: TranslationUnit *_translationUnit; Control *_control; MemoryPool *_pool; - Identifier *_objcInContextKeyword; unsigned _tokenIndex; bool _templateArguments: 1; bool _qtMocRunEnabled: 1;