diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp index 51a3c1ac34899523dc50593dd570c0f4abe65c1c..e8ecfa07cdba7fbcd5948c1d94ee04d05ed4d0c2 100644 --- a/src/shared/cplusplus/AST.cpp +++ b/src/shared/cplusplus/AST.cpp @@ -2241,6 +2241,9 @@ unsigned ObjcPropertyAttributeListAST::lastToken() const unsigned ObjCPropertyDeclarationAST::firstToken() const { + if (attributes) + return attributes->firstToken(); + return property_token; } @@ -2316,4 +2319,150 @@ unsigned ObjCMethodPrototypeAST::lastToken() const return method_type_token + 1; } +unsigned ObjCClassImplementationAST::firstToken() const +{ + return implementation_token; +} + +unsigned ObjCClassImplementationAST::lastToken() const +{ + if (end_token) + return end_token + 1; + + for (DeclarationListAST *it = declarations; it; it = it->next) { + if (! it->next) + return it->lastToken(); + } + + if (inst_vars_decl) + return inst_vars_decl->lastToken(); + if (super_class_identifier) + return super_class_identifier + 1; + if (colon_token) + return colon_token + 1; + if (class_identifier) + return class_identifier + 1; + + return implementation_token + 1; +} + +unsigned ObjCCategoryImplementationAST::firstToken() const +{ + return implementation_token; +} + +unsigned ObjCCategoryImplementationAST::lastToken() const +{ + if (end_token) + return end_token + 1; + + for (DeclarationListAST *it = declarations; it; it = it->next) { + if (! it->next) + return it->lastToken(); + } + + if (rparen_token) + return rparen_token + 1; + if (category_name_token) + return category_name_token + 1; + if (lparen_token) + return lparen_token + 1; + if (class_identifier) + return class_identifier + 1; + + return implementation_token + 1; +} + +unsigned ObjCSynthesizedPropertyAST::firstToken() const +{ + if (property_identifier) + return property_identifier; + else if (equals_token) + return equals_token; + else + return property_alias_identifier; +} + +unsigned ObjCSynthesizedPropertyAST::lastToken() const +{ + if (property_alias_identifier) + return property_alias_identifier + 1; + else if (equals_token) + return equals_token + 1; + else + return property_identifier + 1; +} + +unsigned ObjCSynthesizedPropertyListAST::firstToken() const +{ + if (synthesized_property) + return synthesized_property->firstToken(); + else + return comma_token; +} + +unsigned ObjCSynthesizedPropertyListAST::lastToken() const +{ + for (const ObjCSynthesizedPropertyListAST *it = this; it; it = it->next) { + if (! it->next && it->synthesized_property) { + return it->synthesized_property->lastToken(); + } + } + // ### assert? + return 0; +} + +unsigned ObjCSynthesizedPropertiesDeclarationAST::firstToken() const +{ + return synthesized_token; +} + +unsigned ObjCSynthesizedPropertiesDeclarationAST::lastToken() const +{ + if (semicolon_token) + return semicolon_token + 1; + else if (property_identifiers) + return property_identifiers->lastToken(); + else + return synthesized_token + 1; +} + +unsigned ObjCDynamicPropertiesDeclarationAST::firstToken() const +{ + return dynamic_token; +} + +unsigned ObjCDynamicPropertiesDeclarationAST::lastToken() const +{ + if (semicolon_token) + return semicolon_token + 1; + else if (property_identifiers) + return property_identifiers->lastToken(); + else + return dynamic_token + 1; +} + +unsigned ObjCFastEnumerationAST::firstToken() const +{ + return for_token; +} + +unsigned ObjCFastEnumerationAST::lastToken() const +{ + if (body_statement) + return body_statement->lastToken(); + else if (rparen_token) + return rparen_token + 1; + else if (fast_enumeratable_expression) + return fast_enumeratable_expression->lastToken(); + else if (in_token) + return in_token + 1; + else if (initializer) + return initializer->lastToken(); + else if (lparen_token) + return lparen_token + 1; + else + return for_token + 1; +} + CPLUSPLUS_END_NAMESPACE diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h index 898fd16c87df3c8c771e2cba744fb7190fb2bf11..f6ab2626eb6c6a3d8a24497f255541d7cbfdd694 100644 --- a/src/shared/cplusplus/AST.h +++ b/src/shared/cplusplus/AST.h @@ -2801,6 +2801,7 @@ protected: class CPLUSPLUS_EXPORT ObjCPropertyDeclarationAST: public DeclarationAST { public: + SpecifierAST *attributes; unsigned property_token; unsigned lparen_token; ObjcPropertyAttributeListAST *property_attributes; @@ -2882,6 +2883,158 @@ protected: virtual void accept0(ASTVisitor *visitor); }; +class CPLUSPLUS_EXPORT ObjCClassImplementationAST: public DeclarationAST +{ +public: + unsigned implementation_token; + unsigned class_identifier; + unsigned colon_token; + unsigned super_class_identifier; + ObjCInstanceVariablesDeclarationAST *inst_vars_decl; + DeclarationListAST *declarations; + unsigned end_token; + +public: + virtual ObjCClassImplementationAST *asObjCClassImplementation() + { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual ObjCClassImplementationAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); +}; + +class CPLUSPLUS_EXPORT ObjCCategoryImplementationAST: public DeclarationAST +{ +public: + unsigned implementation_token; + unsigned class_identifier; + unsigned lparen_token; + unsigned category_name_token; + unsigned rparen_token; + DeclarationListAST *declarations; + unsigned end_token; + +public: + virtual ObjCCategoryImplementationAST *asObjCCategoryImplementation() + { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual ObjCCategoryImplementationAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); +}; + +class CPLUSPLUS_EXPORT ObjCSynthesizedPropertyAST: public AST +{ +public: + unsigned property_identifier; + unsigned equals_token; + unsigned property_alias_identifier; + +public: + virtual ObjCSynthesizedPropertyAST *asObjCSynthesizedProperty() + { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual ObjCSynthesizedPropertyAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); +}; + +class CPLUSPLUS_EXPORT ObjCSynthesizedPropertyListAST: public AST +{ +public: + ObjCSynthesizedPropertyAST *synthesized_property; + unsigned comma_token; + ObjCSynthesizedPropertyListAST *next; + +public: + virtual ObjCSynthesizedPropertyListAST *asObjCSynthesizedPropertyList() + { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual ObjCSynthesizedPropertyListAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); +}; + +class CPLUSPLUS_EXPORT ObjCSynthesizedPropertiesDeclarationAST: public DeclarationAST +{ +public: + unsigned synthesized_token; + ObjCSynthesizedPropertyListAST *property_identifiers; + unsigned semicolon_token; + +public: + virtual ObjCSynthesizedPropertiesDeclarationAST *asObjCSynthesizedPropertiesDeclaration() + { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual ObjCSynthesizedPropertiesDeclarationAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); +}; + +class CPLUSPLUS_EXPORT ObjCDynamicPropertiesDeclarationAST: public DeclarationAST +{ +public: + unsigned dynamic_token; + IdentifierListAST *property_identifiers; + unsigned semicolon_token; + +public: + virtual ObjCDynamicPropertiesDeclarationAST *asObjCDynamicPropertiesDeclaration() + { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual ObjCDynamicPropertiesDeclarationAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); +}; + +class CPLUSPLUS_EXPORT ObjCFastEnumerationAST: public StatementAST +{ +public: + unsigned for_token; + unsigned lparen_token; + StatementAST *initializer; + unsigned in_token; + ExpressionAST *fast_enumeratable_expression; + unsigned rparen_token; + StatementAST *body_statement; + +public: + virtual ObjCFastEnumerationAST *asObjCFastEnumeration() + { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual ObjCFastEnumerationAST *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 385958d47c6a11441f07427afe356e78b86912ff..1e160ae2747a583c0824fd92e6d39c7a036adda5 100644 --- a/src/shared/cplusplus/ASTClone.cpp +++ b/src/shared/cplusplus/ASTClone.cpp @@ -1382,6 +1382,7 @@ ObjcPropertyAttributeListAST *ObjcPropertyAttributeListAST::clone(MemoryPool *po ObjCPropertyDeclarationAST *ObjCPropertyDeclarationAST::clone(MemoryPool *pool) const { ObjCPropertyDeclarationAST *ast = new (pool) ObjCPropertyDeclarationAST; + if (attributes) ast->attributes = attributes->clone(pool); ast->property_token = property_token; ast->lparen_token = lparen_token; if (property_attributes) ast->property_attributes = property_attributes->clone(pool); @@ -1419,4 +1420,82 @@ ObjCMethodPrototypeAST *ObjCMethodPrototypeAST::clone(MemoryPool *pool) const return ast; } +ObjCClassImplementationAST *ObjCClassImplementationAST::clone(MemoryPool *pool) const +{ + ObjCClassImplementationAST *ast = new (pool) ObjCClassImplementationAST; + ast->implementation_token = implementation_token; + ast->class_identifier = class_identifier; + ast->colon_token = colon_token; + ast->super_class_identifier = super_class_identifier; + if (inst_vars_decl) ast->inst_vars_decl = inst_vars_decl->clone(pool); + if (declarations) ast->declarations = declarations->clone(pool); + ast->end_token = end_token; + return ast; +} + +ObjCCategoryImplementationAST *ObjCCategoryImplementationAST::clone(MemoryPool *pool) const +{ + ObjCCategoryImplementationAST *ast = new (pool) ObjCCategoryImplementationAST; + ast->implementation_token = implementation_token; + ast->class_identifier = class_identifier; + ast->lparen_token = lparen_token; + ast->category_name_token = category_name_token; + ast->rparen_token = rparen_token; + if (declarations) ast->declarations = declarations->clone(pool); + ast->end_token = end_token; + return ast; +} + +ObjCSynthesizedPropertyAST *ObjCSynthesizedPropertyAST::clone(MemoryPool *pool) const +{ + ObjCSynthesizedPropertyAST *ast = new (pool) ObjCSynthesizedPropertyAST; + ast->property_identifier = property_identifier; + ast->equals_token = equals_token; + ast->property_alias_identifier = property_alias_identifier; + return ast; +} + +ObjCSynthesizedPropertyListAST *ObjCSynthesizedPropertyListAST::clone(MemoryPool *pool) const +{ + ObjCSynthesizedPropertyListAST *ast = new (pool) ObjCSynthesizedPropertyListAST; + if (synthesized_property) ast->synthesized_property = synthesized_property->clone(pool); + ast->comma_token = comma_token; + if (next) ast->next = next->clone(pool); + return ast; +} + +ObjCSynthesizedPropertiesDeclarationAST *ObjCSynthesizedPropertiesDeclarationAST::clone(MemoryPool *pool) const +{ + ObjCSynthesizedPropertiesDeclarationAST *ast = new (pool) ObjCSynthesizedPropertiesDeclarationAST; + ast->synthesized_token = synthesized_token; + if (property_identifiers) ast->property_identifiers = property_identifiers->clone(pool); + ast->semicolon_token = semicolon_token; + return ast; +} + +ObjCDynamicPropertiesDeclarationAST *ObjCDynamicPropertiesDeclarationAST::clone(MemoryPool *pool) const +{ + ObjCDynamicPropertiesDeclarationAST *ast = new (pool) ObjCDynamicPropertiesDeclarationAST; + ast->dynamic_token = dynamic_token; + if (property_identifiers) ast->property_identifiers = property_identifiers->clone(pool); + ast->semicolon_token = semicolon_token; + return ast; +} + +ObjCFastEnumerationAST *ObjCFastEnumerationAST::clone(MemoryPool *pool) const +{ + ObjCFastEnumerationAST *ast = new (pool) ObjCFastEnumerationAST; + ast->for_token = for_token; + ast->lparen_token = lparen_token; + if (initializer) + ast->initializer = initializer->clone(pool); + ast->in_token = in_token; + if (fast_enumeratable_expression) + ast->fast_enumeratable_expression = fast_enumeratable_expression->clone(pool); + ast->rparen_token = rparen_token; + if (body_statement) + ast->body_statement = body_statement->clone(pool); + return ast; +} + CPLUSPLUS_END_NAMESPACE diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp index b6b21ad357191a57f5a69fad1a5523b3cf8c67f5..98fe8a84adb4184788ad742edc701d58fa42c62a 100644 --- a/src/shared/cplusplus/ASTVisit.cpp +++ b/src/shared/cplusplus/ASTVisit.cpp @@ -1318,6 +1318,8 @@ void ObjCPropertyDeclarationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { // visit ObjCPropertyDeclarationAST: + for (SpecifierAST *it = attributes; it; it = it->next) + accept(it, visitor); for (ObjcPropertyAttributeListAST *it = property_attributes; it; it = it->next) accept(it, visitor); if (simple_declaration) @@ -1366,4 +1368,85 @@ void ObjCMethodPrototypeAST::accept0(ASTVisitor *visitor) visitor->endVisit(this); } +void ObjCClassImplementationAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + // visit ObjCClassImplementationAST + if (inst_vars_decl) + accept(inst_vars_decl, visitor); + for (DeclarationListAST *it = declarations; it; it = it->next) + accept(it, visitor); + // visit DeclarationAST + } + visitor->endVisit(this); +} + +void ObjCCategoryImplementationAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + // visit ObjCCategoryImplementationAST + for (DeclarationListAST *it = declarations; it; it = it->next) + accept(it, visitor); + // visit DeclarationAST + } + visitor->endVisit(this); +} + +void ObjCSynthesizedPropertyAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + // visit ObjCSynthesizedPropertyAST + // visit AST + } + visitor->endVisit(this); +} + +void ObjCSynthesizedPropertyListAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + // visit ObjCSynthesizedPropertyListAST + if (synthesized_property) + accept(synthesized_property, visitor); + // visit AST + } + visitor->endVisit(this); +} + +void ObjCSynthesizedPropertiesDeclarationAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + // visit ObjCSynthesizedPropertiesDeclarationAST + for (ObjCSynthesizedPropertyListAST *it = property_identifiers; it; it = it->next) + accept(it, visitor); + // visit DeclarationAST + } + visitor->endVisit(this); +} + +void ObjCDynamicPropertiesDeclarationAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + // visit ObjCDynamicPropertiesDeclarationAST + for (IdentifierListAST *it = property_identifiers; it; it = it->next) + accept(it, visitor); + // visit DeclarationAST + } + visitor->endVisit(this); +} + +void ObjCFastEnumerationAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + // visit ObjCFastEnumerationAST + if (initializer) + accept(initializer, visitor); + if (fast_enumeratable_expression) + accept(fast_enumeratable_expression, visitor); + if (body_statement) + accept(body_statement, visitor); + // visit StatementAST + } + visitor->endVisit(this); +} + CPLUSPLUS_END_NAMESPACE diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h index b272c7077a9bc15ce275cf39ad9ba0befcc9eeba..5279d290f502916a4816eb484bf222b0a1b0e454 100644 --- a/src/shared/cplusplus/ASTVisitor.h +++ b/src/shared/cplusplus/ASTVisitor.h @@ -217,6 +217,13 @@ public: virtual bool visit(ObjCMethodPrototypeAST *) { return true; } virtual bool visit(ObjCMessageArgumentDeclarationListAST *) { return true; } virtual bool visit(ObjCMessageArgumentDeclarationAST *) { return true; } + virtual bool visit(ObjCClassImplementationAST *) { return true; } + virtual bool visit(ObjCCategoryImplementationAST *) { return true; } + virtual bool visit(ObjCSynthesizedPropertyAST *) { return true; } + virtual bool visit(ObjCSynthesizedPropertyListAST *) { return true; } + virtual bool visit(ObjCSynthesizedPropertiesDeclarationAST *) { return true; } + virtual bool visit(ObjCDynamicPropertiesDeclarationAST *) { return true; } + virtual bool visit(ObjCFastEnumerationAST *) { return true; } virtual bool visit(DeclarationListAST *) { return true; } virtual void endVisit(DeclarationListAST *) { } @@ -345,6 +352,13 @@ public: virtual void endVisit(ObjCMethodPrototypeAST *) { } virtual void endVisit(ObjCMessageArgumentDeclarationListAST *) { } virtual void endVisit(ObjCMessageArgumentDeclarationAST *) { } + virtual void endVisit(ObjCClassImplementationAST *) { } + virtual void endVisit(ObjCCategoryImplementationAST *) { } + virtual void endVisit(ObjCSynthesizedPropertyAST *) { } + virtual void endVisit(ObjCSynthesizedPropertyListAST *) { } + virtual void endVisit(ObjCSynthesizedPropertiesDeclarationAST *) { } + virtual void endVisit(ObjCDynamicPropertiesDeclarationAST *) { } + virtual void endVisit(ObjCFastEnumerationAST *) { } private: Control *_control; diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h index f123e736897b5a170cb65b93200f31464780cbdf..5416856614c641251fa7b8681a45cd86de2e4788 100644 --- a/src/shared/cplusplus/ASTfwd.h +++ b/src/shared/cplusplus/ASTfwd.h @@ -190,6 +190,13 @@ class ObjcPropertyAttributeAST; class ObjCMethodPrototypeAST; class ObjCMessageArgumentDeclarationListAST; class ObjCMessageArgumentDeclarationAST; +class ObjCCategoryImplementationAST; +class ObjCClassImplementationAST; +class ObjCSynthesizedPropertyAST; +class ObjCSynthesizedPropertyListAST; +class ObjCSynthesizedPropertiesDeclarationAST; +class ObjCDynamicPropertiesDeclarationAST; +class ObjCFastEnumerationAST; CPLUSPLUS_END_NAMESPACE CPLUSPLUS_END_HEADER diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp index b75c10d9ddca4e63e769543d202dd80e5b04f813..2856e07622ad15cc683747676cd7dc8a32a8221c 100644 --- a/src/shared/cplusplus/Parser.cpp +++ b/src/shared/cplusplus/Parser.cpp @@ -63,6 +63,7 @@ Parser::Parser(TranslationUnit *unit) : _translationUnit(unit), _control(_translationUnit->control()), _pool(_translationUnit->memoryPool()), + _objcInContextKeyword(_control->findOrInsertIdentifier("in")), _tokenIndex(1), _templateArguments(0), _qtMocRunEnabled(false), @@ -422,7 +423,10 @@ bool Parser::parseDeclaration(DeclarationAST *&node) return parseObjCImplementation(node); case T_AT_END: - return parseObjCEnd(node); + // TODO: should this be done here, or higher-up? + _translationUnit->error(cursor(), "skip stray token `%s'", tok().spell()); + consumeToken(); + break; default: { if (_objCEnabled && LA() == T___ATTRIBUTE__) { @@ -2168,20 +2172,43 @@ bool Parser::parseForeachStatement(StatementAST *&node) bool Parser::parseForStatement(StatementAST *&node) { - if (LA() == T_FOR) { + if (LA() != T_FOR) + return false; + + unsigned for_token = consumeToken(); + unsigned lparen_token = 0; + match(T_LPAREN, &lparen_token); + StatementAST *initializer = 0; + parseForInitStatement(initializer); + + if (LA() == T_IDENTIFIER && tok().identifier == _objcInContextKeyword) { + ObjCFastEnumerationAST *ast = new (_pool) ObjCFastEnumerationAST; + + ast->for_token = for_token; + ast->lparen_token = lparen_token; + ast->initializer = initializer; + ast->in_token = consumeToken(); + parseExpression(ast->fast_enumeratable_expression); + match(T_RPAREN, &ast->rparen_token); + parseStatement(ast->body_statement); + + node = ast; + } else { ForStatementAST *ast = new (_pool) ForStatementAST; - ast->for_token = consumeToken(); - match(T_LPAREN, &ast->lparen_token); - parseForInitStatement(ast->initializer); + + ast->for_token = for_token; + ast->lparen_token = lparen_token; + ast->initializer = initializer; parseExpression(ast->condition); match(T_SEMICOLON, &ast->semicolon_token); parseExpression(ast->expression); match(T_RPAREN, &ast->rparen_token); parseStatement(ast->statement); + node = ast; - return true; } - return false; + + return true; } bool Parser::parseForInitStatement(StatementAST *&node) @@ -3951,7 +3978,7 @@ bool Parser::parseObjCInterface(DeclarationAST *&node, "invalid attributes for category interface declaration"); ObjCCategoryInterfaceDeclarationAST *ast = new (_pool) ObjCCategoryInterfaceDeclarationAST; - // XXX: Should the attributes get stored anyway? (for fixing/refactoring purposes maybe...) + // TODO: Should the attributes get stored anyway? (for fixing/refactoring purposes maybe...) ast->interface_token = objc_interface_token; ast->class_identifier_token = identifier_token; @@ -4074,48 +4101,62 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node, // objc-class-instance-variables-opt // objc-implementation ::= T_AT_IMPLEMENTAION T_IDENTIFIER T_LPAREN T_IDENTIFIER T_RPAREN // -bool Parser::parseObjCImplementation(DeclarationAST *&) +bool Parser::parseObjCImplementation(DeclarationAST *&node) { if (LA() != T_AT_IMPLEMENTATION) return false; - consumeToken(); - + unsigned implementation_token = consumeToken(); unsigned identifier_token = 0; match(T_IDENTIFIER, &identifier_token); if (LA() == T_LPAREN) { // a category implementation - unsigned lparen_token = 0, rparen_token = 0; - unsigned category_name_token = 0; - match(T_LPAREN, &lparen_token); - match(T_IDENTIFIER, &category_name_token); - match(T_RPAREN, &rparen_token); - return true; - } + ObjCCategoryImplementationAST *ast = new (_pool) ObjCCategoryImplementationAST; + ast->implementation_token = implementation_token; + ast->class_identifier = identifier_token; - // a class implementation - if (LA() == T_COLON) { - consumeToken(); - unsigned super_class_name_token = 0; - match(T_IDENTIFIER, &super_class_name_token); + match(T_LPAREN, &(ast->lparen_token)); + match(T_IDENTIFIER, &(ast->category_name_token)); + match(T_RPAREN, &(ast->rparen_token)); + + parseObjCMethodDefinitionList(ast->declarations); + match(T_AT_END, &(ast->end_token)); + + node = ast; + } else { + // a class implementation + ObjCClassImplementationAST *ast = new (_pool) ObjCClassImplementationAST; + ast->implementation_token = implementation_token; + ast->class_identifier = identifier_token; + + if (LA() == T_COLON) { + ast->colon_token = consumeToken(); + match(T_IDENTIFIER, &(ast->super_class_identifier)); + } + + parseObjClassInstanceVariables(ast->inst_vars_decl); + parseObjCMethodDefinitionList(ast->declarations); + match(T_AT_END, &(ast->end_token)); + + node = ast; } - ObjCInstanceVariablesDeclarationAST *inst_vars_decl; - parseObjClassInstanceVariables(inst_vars_decl); - parseObjCMethodDefinitionList(); return true; } -bool Parser::parseObjCMethodDefinitionList() +bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node) { + DeclarationListAST **next = &node; + while (LA() && LA() != T_AT_END) { unsigned start = cursor(); + DeclarationAST *declaration = 0; switch (LA()) { case T_PLUS: case T_MINUS: - parseObjCMethodDefinition(); + parseObjCMethodDefinition(declaration); if (start == cursor()) consumeToken(); @@ -4126,7 +4167,9 @@ bool Parser::parseObjCMethodDefinitionList() break; case T_AT_SYNTHESIZE: { - consumeToken(); + ObjCSynthesizedPropertiesDeclarationAST *ast = new (_pool) ObjCSynthesizedPropertiesDeclarationAST; + ast->synthesized_token = consumeToken(); + // TODO EV unsigned identifier_token = 0; match(T_IDENTIFIER, &identifier_token); @@ -4150,34 +4193,36 @@ bool Parser::parseObjCMethodDefinitionList() } } - unsigned semicolon_token = 0; - match(T_SEMICOLON, &semicolon_token); + match(T_SEMICOLON, &(ast->semicolon_token)); + declaration = ast; break; } case T_AT_DYNAMIC: { - consumeToken(); - unsigned identifier_token = 0; - match(T_IDENTIFIER, &identifier_token); + ObjCDynamicPropertiesDeclarationAST *ast = new (_pool) ObjCDynamicPropertiesDeclarationAST; + ast->dynamic_token = consumeToken(); + ast->property_identifiers = new (_pool) IdentifierListAST; + match(T_IDENTIFIER, &(ast->property_identifiers->identifier_token)); + IdentifierListAST *last = ast->property_identifiers; while (LA() == T_COMMA) { - consumeToken(); - match(T_IDENTIFIER, &identifier_token); + last->comma_token = consumeToken(); + last->next = new (_pool) IdentifierListAST; + last = last->next; + match(T_IDENTIFIER, &(last->identifier_token)); } - unsigned semicolon_token = 0; - match(T_SEMICOLON, &semicolon_token); + match(T_SEMICOLON, &(ast->semicolon_token)); + declaration = ast; break; } default: if (LA() == T_EXTERN && LA(2) == T_STRING_LITERAL) { - DeclarationAST *declaration = 0; parseDeclaration(declaration); } else { - DeclarationAST *declaration = 0; if (! parseBlockDeclaration(declaration)) { rewind(start); _translationUnit->error(cursor(), @@ -4188,13 +4233,20 @@ bool Parser::parseObjCMethodDefinitionList() } break; } // switch + + if (declaration) { + *next = new (_pool) DeclarationListAST; + (*next)->declaration = declaration; + next = &((*next)->next); + } } return true; } -bool Parser::parseObjCMethodDefinition() +bool Parser::parseObjCMethodDefinition(DeclarationAST *&node) { + // TODO EV: DeclarationAST *ast = 0; if (! parseObjCMethodPrototype(ast)) return false; @@ -4339,12 +4391,13 @@ bool Parser::parseObjCInstanceVariableDeclaration(DeclarationAST *&node) // objc-property-declaration ::= // T_AT_PROPERTY T_LPAREN (property-attribute @ T_COMMA) T_RPAREN simple-declaration // -bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&node, SpecifierAST *) +bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&node, SpecifierAST *attributes) { if (LA() != T_AT_PROPERTY) return false; ObjCPropertyDeclarationAST *ast = new (_pool) ObjCPropertyDeclarationAST; + ast->attributes = attributes; ast->property_token = consumeToken(); if (LA() == T_LPAREN) { @@ -4518,15 +4571,4 @@ bool Parser::parseObjCTypeQualifiers(unsigned &type_qualifier) return true; } -// objc-end: T_AT_END -bool Parser::parseObjCEnd(DeclarationAST *&) -{ - if (LA() != T_AT_END) - return false; - - consumeToken(); - return true; -} - - CPLUSPLUS_END_NAMESPACE diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h index d29749834442873802825806d6d115c7a8e8c3bc..df017209e158c574b2913a38056bcd3a31dd1b6e 100644 --- a/src/shared/cplusplus/Parser.h +++ b/src/shared/cplusplus/Parser.h @@ -228,8 +228,8 @@ public: bool parseObjCMessageReceiver(ExpressionAST *&node); bool parseObjCMessageArguments(ObjCMessageArgumentListAST *&node); bool parseObjCSelectorArg(ObjCMessageArgumentAST *&node); - bool parseObjCMethodDefinitionList(); - bool parseObjCMethodDefinition(); + bool parseObjCMethodDefinitionList(DeclarationListAST *&node); + bool parseObjCMethodDefinition(DeclarationAST *&node); bool parseObjCProtocolRefs(ObjCProtocolRefsAST *&node); bool parseObjClassInstanceVariables(ObjCInstanceVariablesDeclarationAST *&node); @@ -244,7 +244,6 @@ public: bool parseObjCSelector(unsigned &selector_token); bool parseObjCKeywordDeclaration(ObjCMessageArgumentDeclarationAST *&node); bool parseObjCTypeQualifiers(unsigned &type_qualifier); - bool parseObjCEnd(DeclarationAST *&node); bool lookAtObjCSelector() const; @@ -288,6 +287,7 @@ private: TranslationUnit *_translationUnit; Control *_control; MemoryPool *_pool; + Identifier *_objcInContextKeyword; unsigned _tokenIndex; bool _templateArguments: 1; bool _qtMocRunEnabled: 1;