From c5f9695fe1ac1606fe82b6a2b75bafa454a400c6 Mon Sep 17 00:00:00 2001 From: Roberto Raggi <qtc-committer@nokia.com> Date: Thu, 8 Jan 2009 18:05:33 +0100 Subject: [PATCH] More work on ObjC++ support. --- shared/cplusplus/Parser.cpp | 165 +++++++++++++++++++++++++++++++++--- shared/cplusplus/Parser.h | 17 +++- 2 files changed, 166 insertions(+), 16 deletions(-) diff --git a/shared/cplusplus/Parser.cpp b/shared/cplusplus/Parser.cpp index c1e48f233f4..67fed9e0118 100644 --- a/shared/cplusplus/Parser.cpp +++ b/shared/cplusplus/Parser.cpp @@ -68,6 +68,7 @@ Parser::Parser(TranslationUnit *unit) _tokenIndex(1), _templateArguments(0), _qtMocRunEnabled(false), + _objcEnabled(false), _inFunctionBody(false) { } @@ -2532,7 +2533,16 @@ bool Parser::parsePrimaryExpression(ExpressionAST *&node) case T_SLOT: return parseQtMethod(node); + case T_AT_ENCODE: + case T_AT_PROTOCOL: + case T_AT_SELECTOR: + case T_AT_STRING_LITERAL: + return parseObjCExpression(node); + default: { + if (_objcEnabled && LA() == T_LBRACKET) + return parseObjCExpression(node); + unsigned startOfName = cursor(); NameAST *name = 0; if (parseName(name)) { @@ -3296,17 +3306,17 @@ bool Parser::parseObjCClassDeclaration(DeclarationAST *&node) return true; } -bool Parser::parseObjCInterfaceDeclaration(DeclarationAST *&node) +bool Parser::parseObjCInterfaceDeclaration(DeclarationAST *&) { if (LA() != T_AT_INTERFACE) return false; - unsigned interface_token = consumeToken(); + /*unsigned interface_token = */ consumeToken(); unsigned interface_name_token = 0; match(T_IDENTIFIER, &interface_name_token); if (LA() == T_LPAREN) { // category interface - unsigned lparen_token = consumeToken(); + /*unsigned lparen_token = */ consumeToken(); unsigned catagory_name_token = 0; if (LA() == T_IDENTIFIER) catagory_name_token = consumeToken(); @@ -3335,27 +3345,27 @@ bool Parser::parseObjCInterfaceDeclaration(DeclarationAST *&node) return false; } -bool Parser::parseObjCProtocolDeclaration(DeclarationAST *&node) +bool Parser::parseObjCProtocolDeclaration(DeclarationAST *&) { return false; } -bool Parser::parseObjCEndDeclaration(DeclarationAST *&node) +bool Parser::parseObjCEndDeclaration(DeclarationAST *&) { return false; } -bool Parser::parseObjCAliasDeclaration(DeclarationAST *&node) +bool Parser::parseObjCAliasDeclaration(DeclarationAST *&) { return false; } -bool Parser::parseObjCPropertySynthesize(DeclarationAST *&node) +bool Parser::parseObjCPropertySynthesize(DeclarationAST *&) { return false; } -bool Parser::parseObjCPropertyDynamic(DeclarationAST *&node) +bool Parser::parseObjCPropertyDynamic(DeclarationAST *&) { return false; } @@ -3419,15 +3429,16 @@ bool Parser::parseObjCInterfaceMemberDeclaration() default: { DeclarationAST *declaration = 0; - parseDeclaration(declaration); + if (parseDeclaration(declaration)) + return true; } // default } // switch - return true; + return false; } -bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&ast) +bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&) { return false; } @@ -3438,8 +3449,7 @@ bool Parser::parseObjCMethodPrototype() return false; // instance or class method? - unsigned method_type_token = consumeToken(); - + /*unsigned method_type_token = */ consumeToken(); SpecifierAST *attributes = 0, **attr = &attributes; while (parseAttributeSpecifier(*attr)) @@ -3448,6 +3458,135 @@ bool Parser::parseObjCMethodPrototype() return false; } +bool Parser::parseObjCExpression(ExpressionAST *&node) +{ + switch (LA()) { + case T_LBRACKET: + return parseObjCMessageExpression(node); + + case T_AT_STRING_LITERAL: + return parseObjCStringLiteral(node); + + case T_AT_ENCODE: + return parseObjCEncodeExpression(node); + + case T_AT_PROTOCOL: + return parseObjCProtocolExpression(node); + + case T_AT_SELECTOR: + return parseObjCSelectorExpression(node); + } + return false; +} + +bool Parser::parseObjCMessageExpression(ExpressionAST *&) +{ + if (LA() != T_LBRACKET) + return false; + + /*unsigned lbracket_token = */ consumeToken(); + ExpressionAST *receiver = 0; + parseObjCMessageReceiver(receiver); + parseObjCMessageArguments(); + unsigned rbracket_token = 0; + match(T_RBRACKET, &rbracket_token); + return true; +} + +bool Parser::parseObjCStringLiteral(ExpressionAST *&) +{ + if (LA() != T_AT_STRING_LITERAL) + return false; + + do { + consumeToken(); + } while (LA() == T_AT_STRING_LITERAL); + + return true; +} + +bool Parser::parseObjCEncodeExpression(ExpressionAST *&) +{ + if (LA() != T_AT_ENCODE) + return false; + + /*unsigned encode_token = */ consumeToken(); + unsigned lparen_token = 0, rparen_token = 0; + match(T_LPAREN, &lparen_token); + SpecifierAST *type_specifier = 0; + parseSimpleTypeSpecifier(type_specifier); + match(T_RPAREN, &rparen_token); + return true; +} + +bool Parser::parseObjCProtocolExpression(ExpressionAST *&) +{ + if (LA() != T_AT_PROTOCOL) + return false; + + /*unsigned protocol_token = */ consumeToken(); + unsigned protocol_name_token = 0, lparen_token = 0, rparen_token = 0; + match(T_LPAREN, &lparen_token); + match(T_IDENTIFIER, &protocol_name_token); + match(T_RPAREN, &rparen_token); + return true; +} + +bool Parser::parseObjCSelectorExpression(ExpressionAST *&) +{ + if (LA() != T_AT_SELECTOR) + return false; + + /*unsigned selector_token = */ consumeToken(); + unsigned lparen_token = 0, rparen_token = 0; + match(T_LPAREN, &lparen_token); + while (LA(1) == T_IDENTIFIER && LA(2) == T_COLON) { + /*unsigned identifier_token = */ consumeToken(); + /*unsigned colon_token = */ consumeToken(); + } + match(T_RPAREN, &rparen_token); + return true; +} + +bool Parser::parseObjCMessageReceiver(ExpressionAST *&node) +{ + // ### expression or simple-type-specifier. + return parseExpression(node); +} + +bool Parser::parseObjCMessageArguments() +{ + if (LA() != T_IDENTIFIER && LA() != T_COLON) + return false; + unsigned selector_name_token = 0; + + if (LA() == T_IDENTIFIER) + selector_name_token = consumeToken(); + + if (LA() == T_COLON) { + /*unsigned colon_token = */ consumeToken(); + + ExpressionAST *expr = 0; + parseAssignmentExpression(expr); + + while ((LA() == T_IDENTIFIER && LA(2) == T_COLON) || LA() == T_COLON) { + if (LA() == T_IDENTIFIER) + consumeToken(); + + if (LA() == T_COLON) + consumeToken(); + + parseAssignmentExpression(expr); + } + + while (LA() == T_COMMA) { + consumeToken(); + parseAssignmentExpression(expr); + } + } + + return true; +} CPLUSPLUS_END_NAMESPACE diff --git a/shared/cplusplus/Parser.h b/shared/cplusplus/Parser.h index 1eac8ce7652..8bde1cccc46 100644 --- a/shared/cplusplus/Parser.h +++ b/shared/cplusplus/Parser.h @@ -214,13 +214,23 @@ public: bool parseObjCIdentifierList(IdentifierListAST *&node); - bool parseObjCPropertyDeclaration(DeclarationAST *&ast); + bool parseObjCPropertyDeclaration(DeclarationAST *&node); bool parseObjCProtocolRefs(); bool parseObjCClassInstanceVariables(); bool parseObjCInterfaceMemberDeclaration(); bool parseObjCInterfaceDeclList(); bool parseObjCMethodPrototype(); + bool parseObjCExpression(ExpressionAST *&node); + bool parseObjCMessageExpression(ExpressionAST *&node); + bool parseObjCStringLiteral(ExpressionAST *&node); + bool parseObjCEncodeExpression(ExpressionAST *&node); + bool parseObjCProtocolExpression(ExpressionAST *&node); + bool parseObjCSelectorExpression(ExpressionAST *&node); + + bool parseObjCMessageReceiver(ExpressionAST *&node); + bool parseObjCMessageArguments(); + // Qt MOC run bool parseQtMethod(ExpressionAST *&node); @@ -245,8 +255,8 @@ private: bool switchTemplateArguments(bool templateArguments); bool blockErrors(bool block); - inline const Token &tok() const - { return _translationUnit->tokenAt(_tokenIndex); } + inline const Token &tok(int i = 1) const + { return _translationUnit->tokenAt(_tokenIndex + i - 1); } inline int LA(int n = 1) const { return _translationUnit->tokenKind(_tokenIndex + n - 1); } @@ -267,6 +277,7 @@ private: unsigned _tokenIndex; bool _templateArguments: 1; bool _qtMocRunEnabled: 1; + bool _objcEnabled: 1; bool _inFunctionBody: 1; private: -- GitLab