diff options
| author | hjk <qtc-committer@nokia.com> | 2009-02-05 17:07:18 +0100 |
|---|---|---|
| committer | hjk <qtc-committer@nokia.com> | 2009-02-05 17:07:18 +0100 |
| commit | 4ef83082f6f5a74caff81e6fcc2d26aff9ef47c8 (patch) | |
| tree | b1beddb186ccf947136f10f80afe5044375fa18c /src/shared/cplusplus | |
| parent | 58e8aed6f0115cc184510d7d2fbb5944c47de6e3 (diff) | |
| parent | 68552b8f4d88f31462270f66774dcc9ec6755c1a (diff) | |
| download | qt-creator-4ef83082f6f5a74caff81e6fcc2d26aff9ef47c8.tar.gz | |
Merge branch 'master' of git@scm.dev.nokia.troll.no:creator/mainline
Diffstat (limited to 'src/shared/cplusplus')
| -rw-r--r-- | src/shared/cplusplus/AST.cpp | 14 | ||||
| -rw-r--r-- | src/shared/cplusplus/AST.h | 4 | ||||
| -rw-r--r-- | src/shared/cplusplus/ObjectiveCTypeQualifiers.cpp | 124 | ||||
| -rw-r--r-- | src/shared/cplusplus/ObjectiveCTypeQualifiers.h | 56 | ||||
| -rw-r--r-- | src/shared/cplusplus/Parser.cpp | 294 | ||||
| -rw-r--r-- | src/shared/cplusplus/Parser.h | 16 | ||||
| -rw-r--r-- | src/shared/cplusplus/PrettyPrinter.cpp | 6 | ||||
| -rw-r--r-- | src/shared/cplusplus/cplusplus.pri | 5 |
8 files changed, 482 insertions, 37 deletions
diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp index 3d710db366..d0ac090099 100644 --- a/src/shared/cplusplus/AST.cpp +++ b/src/shared/cplusplus/AST.cpp @@ -611,8 +611,7 @@ AsmDefinitionAST *AsmDefinitionAST::clone(MemoryPool *pool) const { AsmDefinitionAST *ast = new (pool) AsmDefinitionAST; ast->asm_token = asm_token; - if (cv_qualifier_seq) - ast->cv_qualifier_seq = cv_qualifier_seq->clone(pool); + ast->volatile_token = volatile_token; ast->lparen_token = lparen_token; ast->rparen_token = rparen_token; ast->semicolon_token = semicolon_token; @@ -622,9 +621,7 @@ AsmDefinitionAST *AsmDefinitionAST::clone(MemoryPool *pool) const void AsmDefinitionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - for (SpecifierAST *spec = cv_qualifier_seq; spec; - spec = spec->next) - accept(spec, visitor); + // ### accept the asm operand list. } } @@ -641,11 +638,8 @@ unsigned AsmDefinitionAST::lastToken() const return rparen_token + 1; else if (lparen_token) return lparen_token + 1; - for (SpecifierAST *it = cv_qualifier_seq; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } - + else if (volatile_token) + return volatile_token + 1; return asm_token + 1; } diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h index d7f346c5b0..1918ee7953 100644 --- a/src/shared/cplusplus/AST.h +++ b/src/shared/cplusplus/AST.h @@ -397,8 +397,10 @@ class CPLUSPLUS_EXPORT AsmDefinitionAST: public DeclarationAST { public: unsigned asm_token; - SpecifierAST *cv_qualifier_seq; + unsigned volatile_token; unsigned lparen_token; + // ### string literals + // ### asm operand list unsigned rparen_token; unsigned semicolon_token; diff --git a/src/shared/cplusplus/ObjectiveCTypeQualifiers.cpp b/src/shared/cplusplus/ObjectiveCTypeQualifiers.cpp new file mode 100644 index 0000000000..0bcff3202c --- /dev/null +++ b/src/shared/cplusplus/ObjectiveCTypeQualifiers.cpp @@ -0,0 +1,124 @@ +/*************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** +** Non-Open Source Usage +** +** Licensees may use this file in accordance with the Qt Beta Version +** License Agreement, Agreement version 2.2 provided with the Software or, +** alternatively, in accordance with the terms contained in a written +** agreement between you and Nokia. +** +** GNU General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the packaging +** of this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt GPL Exception +** version 1.3, included in the file GPL_EXCEPTION.txt in this package. +** +***************************************************************************/ + +#include "ObjectiveCTypeQualifiers.h" + +CPLUSPLUS_BEGIN_NAMESPACE + +static inline int classify2(const char *s) { + if (s[0] == 'i') { + if (s[1] == 'n') { + return Token_in; + } + } + return Token_identifier; +} + +static inline int classify3(const char *s) { + if (s[0] == 'o') { + if (s[1] == 'u') { + if (s[2] == 't') { + return Token_out; + } + } + } + return Token_identifier; +} + +static inline int classify5(const char *s) { + if (s[0] == 'b') { + if (s[1] == 'y') { + if (s[2] == 'r') { + if (s[3] == 'e') { + if (s[4] == 'f') { + return Token_byref; + } + } + } + } + } + else if (s[0] == 'i') { + if (s[1] == 'n') { + if (s[2] == 'o') { + if (s[3] == 'u') { + if (s[4] == 't') { + return Token_inout; + } + } + } + } + } + return Token_identifier; +} + +static inline int classify6(const char *s) { + if (s[0] == 'b') { + if (s[1] == 'y') { + if (s[2] == 'c') { + if (s[3] == 'o') { + if (s[4] == 'p') { + if (s[5] == 'y') { + return Token_bycopy; + } + } + } + } + } + } + else if (s[0] == 'o') { + if (s[1] == 'n') { + if (s[2] == 'e') { + if (s[3] == 'w') { + if (s[4] == 'a') { + if (s[5] == 'y') { + return Token_oneway; + } + } + } + } + } + } + return Token_identifier; +} + +int classifyObjectiveCTypeQualifiers(const char *s, int n) { + switch (n) { + case 2: return classify2(s); + case 3: return classify3(s); + case 5: return classify5(s); + case 6: return classify6(s); + default: return Token_identifier; + } // switch +} + +CPLUSPLUS_END_NAMESPACE diff --git a/src/shared/cplusplus/ObjectiveCTypeQualifiers.h b/src/shared/cplusplus/ObjectiveCTypeQualifiers.h new file mode 100644 index 0000000000..5dd7a7609b --- /dev/null +++ b/src/shared/cplusplus/ObjectiveCTypeQualifiers.h @@ -0,0 +1,56 @@ +/*************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** +** Non-Open Source Usage +** +** Licensees may use this file in accordance with the Qt Beta Version +** License Agreement, Agreement version 2.2 provided with the Software or, +** alternatively, in accordance with the terms contained in a written +** agreement between you and Nokia. +** +** GNU General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the packaging +** of this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt GPL Exception +** version 1.3, included in the file GPL_EXCEPTION.txt in this package. +** +***************************************************************************/ +#ifndef CPLUSPLUS_OBJC_TYPEQUALIFIERS_H +#define CPLUSPLUS_OBJC_TYPEQUALIFIERS_H + +#include "CPlusPlusForwardDeclarations.h" + +CPLUSPLUS_BEGIN_HEADER +CPLUSPLUS_BEGIN_NAMESPACE + +enum { + Token_in, + Token_out, + Token_byref, + Token_inout, + Token_bycopy, + Token_oneway, + Token_identifier +}; + +CPLUSPLUS_EXPORT int classifyObjectiveCTypeQualifiers(const char *s, int n); + +CPLUSPLUS_END_NAMESPACE +CPLUSPLUS_END_HEADER + +#endif // CPLUSPLUS_OBJC_TYPEQUALIFIERS_H diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp index 572c9f6665..6fb2da600d 100644 --- a/src/shared/cplusplus/Parser.cpp +++ b/src/shared/cplusplus/Parser.cpp @@ -56,6 +56,7 @@ #include "Control.h" #include "AST.h" #include "Literals.h" +#include "ObjectiveCTypeQualifiers.h" #include <cstdlib> #include <cstring> #include <cassert> @@ -627,22 +628,92 @@ bool Parser::parseTemplateArgumentList(TemplateArgumentListAST *&node) bool Parser::parseAsmDefinition(DeclarationAST *&node) { - if (LA() == T_ASM) { - AsmDefinitionAST *ast = new (_pool) AsmDefinitionAST; - ast->asm_token = consumeToken(); - parseCvQualifiers(ast->cv_qualifier_seq); - if (LA() == T_LPAREN) { - ast->lparen_token = cursor(); - if (skip(T_LPAREN, T_RPAREN)) - ast->rparen_token = consumeToken(); + if (LA() != T_ASM) + return false; + + AsmDefinitionAST *ast = new (_pool) AsmDefinitionAST; + ast->asm_token = consumeToken(); + + if (LA() == T_VOLATILE) + ast->volatile_token = consumeToken(); + + match(T_LPAREN, &ast->lparen_token); + unsigned string_literal_token = 0; + match(T_STRING_LITERAL, &string_literal_token); + while (LA() == T_STRING_LITERAL) { + consumeToken(); + } + if (LA() == T_COLON) { + consumeToken(); // skip T_COLON + parseAsmOperandList(); + if (LA() == T_COLON) { + consumeToken(); + parseAsmOperandList(); + if (LA() == T_COLON) { + consumeToken(); + parseAsmClobberList(); + } + } else if (LA() == T_COLON_COLON) { + consumeToken(); + parseAsmClobberList(); + } + } else if (LA() == T_COLON_COLON) { + consumeToken(); + parseAsmClobberList(); + } + match(T_RPAREN, &ast->rparen_token); + match(T_SEMICOLON, &ast->semicolon_token); + node = ast; + return true; +} + +bool Parser::parseAsmOperandList() +{ + if (parseAsmOperand()) { + while (LA() == T_COMMA) { + consumeToken(); + parseAsmOperand(); } - match(T_SEMICOLON, &ast->semicolon_token); - node = ast; return true; } return false; } +bool Parser::parseAsmOperand() +{ + unsigned string_literal_token = 0; + match(T_STRING_LITERAL, &string_literal_token); + + if (LA() == T_LBRACKET) { + /*unsigned lbracket_token = */ consumeToken(); + match(T_STRING_LITERAL, &string_literal_token); + unsigned rbracket_token = 0; + match(T_RBRACKET, &rbracket_token); + } + + unsigned lparen_token = 0, rparen_token = 0; + match(T_LPAREN, &lparen_token); + ExpressionAST *expression = 0; + parseExpression(expression); + match(T_RPAREN, &rparen_token); + return true; +} + +bool Parser::parseAsmClobberList() +{ + if (LA() != T_STRING_LITERAL) + return false; + + unsigned string_literal_token = consumeToken(); + + while (LA() == T_COMMA) { + consumeToken(); + match(T_STRING_LITERAL, &string_literal_token); + } + + return true; +} + bool Parser::parseTemplateDeclaration(DeclarationAST *&node) { if (! (LA(1) == T_TEMPLATE || ((LA(1) == T_EXPORT || LA(1) == T_EXTERN) @@ -2556,6 +2627,13 @@ bool Parser::parsePrimaryExpression(ExpressionAST *&node) case T_SLOT: return parseQtMethod(node); + case T_LBRACKET: + case T_AT_STRING_LITERAL: + case T_AT_ENCODE: + case T_AT_PROTOCOL: + case T_AT_SELECTOR: + return parseObjCExpression(node); + default: { NameAST *name = 0; if (parseNameId(name)) { @@ -2570,6 +2648,151 @@ bool Parser::parsePrimaryExpression(ExpressionAST *&node) return false; } +bool Parser::parseObjCExpression(ExpressionAST *&node) +{ + switch (LA()) { + case T_AT_ENCODE: + return parseObjCEncodeExpression(node); + + case T_AT_PROTOCOL: + return parseObjCProtocolExpression(node); + + case T_AT_SELECTOR: + return parseObjCSelectorExpression(node); + + case T_LBRACKET: + return parseObjCMessageExpression(node); + + case T_AT_STRING_LITERAL: + return parseObjCStringLiteral(node); + + default: + break; + } // switch + return false; +} + +bool Parser::parseObjCStringLiteral(ExpressionAST *&node) +{ + if (LA() != T_AT_STRING_LITERAL) + return false; + + StringLiteralAST **ast = reinterpret_cast<StringLiteralAST **> (&node); + + while (LA() == T_AT_STRING_LITERAL) { + *ast = new (_pool) StringLiteralAST; + (*ast)->token = consumeToken(); + ast = &(*ast)->next; + } + return true; +} + +bool Parser::parseObjCEncodeExpression(ExpressionAST *&) +{ + if (LA() != T_AT_ENCODE) + return false; + + /*unsigned encode_token = */ consumeToken(); + parseObjCTypeName(); + return true; +} + +bool Parser::parseObjCProtocolExpression(ExpressionAST *&) +{ + if (LA() != T_AT_PROTOCOL) + return false; + + /*unsigned protocol_token = */ consumeToken(); + unsigned lparen_token = 0, identifier_token = 0, rparen_token = 0; + match(T_LPAREN, &lparen_token); + match(T_IDENTIFIER, &identifier_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); + parseObjCMethodSignature(); + match(T_RPAREN, &rparen_token); + return true; +} + +bool Parser::parseObjCMessageExpression(ExpressionAST *&) +{ + if (LA() != T_LBRACKET) + return false; + + /*unsigned lbracket_token = */ consumeToken(); + + parseObjCMessageReceiver(); + parseObjCMessageArguments(); + + unsigned rbracket_token = 0; + match(T_RBRACKET, &rbracket_token); + return true; +} + +bool Parser::parseObjCMessageReceiver() +{ + ExpressionAST *expression = 0; + return parseExpression(expression); +} + +bool Parser::parseObjCMessageArguments() +{ + if (LA() == T_RBRACKET) + return false; // nothing to do. + + unsigned start = cursor(); + + if (parseObjCSelectorArgs()) { + while (parseObjCSelectorArgs()) { + // accept the selector args. + } + } else { + rewind(start); + parseObjCSelector(); + } + + while (LA() == T_COMMA) { + consumeToken(); // skip T_COMMA + ExpressionAST *expression = 0; + parseAssignmentExpression(expression); + } + return true; +} + +bool Parser::parseObjCSelectorArgs() +{ + parseObjCSelector(); + if (LA() != T_COLON) + return false; + + /*unsigned colon_token = */consumeToken(); + + ExpressionAST *expression = 0; + parseAssignmentExpression(expression); + return true; +} + +bool Parser::parseObjCMethodSignature() +{ + if (parseObjCSelector()) { + while (LA() == T_COMMA) { + consumeToken(); // skip T_COMMA + parseObjCSelector(); + } + return true; + } + return false; +} + bool Parser::parseNameId(NameAST *&name) { unsigned start = cursor(); @@ -3522,6 +3745,42 @@ bool Parser::parseObjCImplementation(DeclarationAST *&) } parseObjClassInstanceVariables(); + parseObjCMethodDefinitionList(); + return true; +} + +bool Parser::parseObjCMethodDefinitionList() +{ + while (LA() && LA() != T_AT_END) { + unsigned start = cursor(); + + switch (LA()) { + case T_PLUS: + case T_MINUS: + parseObjCMethodDefinition(); + + if (start == cursor()) + consumeToken(); + break; + + default: + // ### warning message + consumeToken(); + break; + } // switch + } + + return true; +} + +bool Parser::parseObjCMethodDefinition() +{ + if (LA() != T_MINUS && LA() != T_PLUS) + return false; + + parseObjCMethodSignature(); + StatementAST *function_body = 0; + parseFunctionBody(function_body); return true; } @@ -3785,16 +4044,11 @@ bool Parser::parseObjCTypeQualifiers() return false; Identifier *id = tok().identifier; - if (! strcmp("in", id->chars()) || - ! strcmp("out", id->chars()) || - ! strcmp("inout", id->chars()) || - ! strcmp("bycopy", id->chars()) || - ! strcmp("byref", id->chars()) || - ! strcmp("oneway", id->chars())) { - consumeToken(); - return true; - } - return false; + const int k = classifyObjectiveCTypeQualifiers(id->chars(), id->size()); + if (k == Token_identifier) + return false; + consumeToken(); + return true; } // objc-end: T_AT_END diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h index d99d8d27fc..e6a29d199e 100644 --- a/src/shared/cplusplus/Parser.h +++ b/src/shared/cplusplus/Parser.h @@ -85,6 +85,9 @@ public: bool parseAdditiveExpression(ExpressionAST *&node); bool parseAndExpression(ExpressionAST *&node); bool parseAsmDefinition(DeclarationAST *&node); + bool parseAsmOperandList(); + bool parseAsmOperand(); + bool parseAsmClobberList(); bool parseAssignmentExpression(ExpressionAST *&node); bool parseBaseClause(BaseSpecifierAST *&node); bool parseBaseSpecifier(BaseSpecifierAST *&node); @@ -211,12 +214,25 @@ public: bool parseQtMethod(ExpressionAST *&node); // ObjC++ + bool parseObjCExpression(ExpressionAST *&node); bool parseObjCClassDeclaration(DeclarationAST *&node); bool parseObjCInterface(DeclarationAST *&node, SpecifierAST *attributes = 0); bool parseObjCProtocol(DeclarationAST *&node, SpecifierAST *attributes = 0); + bool parseObjCEncodeExpression(ExpressionAST *&node); + bool parseObjCProtocolExpression(ExpressionAST *&node); + bool parseObjCSelectorExpression(ExpressionAST *&node); + bool parseObjCStringLiteral(ExpressionAST *&node); + bool parseObjCMethodSignature(); + bool parseObjCMessageExpression(ExpressionAST *&node); + bool parseObjCMessageReceiver(); + bool parseObjCMessageArguments(); + bool parseObjCSelectorArgs(); + bool parseObjCMethodDefinitionList(); + bool parseObjCMethodDefinition(); + bool parseObjCProtocolRefs(); bool parseObjClassInstanceVariables(); bool parseObjCInterfaceMemberDeclaration(); diff --git a/src/shared/cplusplus/PrettyPrinter.cpp b/src/shared/cplusplus/PrettyPrinter.cpp index 6acb109dcf..d6c604c3ab 100644 --- a/src/shared/cplusplus/PrettyPrinter.cpp +++ b/src/shared/cplusplus/PrettyPrinter.cpp @@ -101,10 +101,8 @@ bool PrettyPrinter::visit(ArrayInitializerAST *ast) bool PrettyPrinter::visit(AsmDefinitionAST *ast) { out << spell(ast->asm_token); - for (SpecifierAST *it = ast->cv_qualifier_seq; it; it = it->next) { - out << ' '; - accept(it); - } + if (ast->volatile_token) + out << ' ' << spell(ast->volatile_token) << ' '; out << '('; out << "/* ### implement me */"; out << ");"; diff --git a/src/shared/cplusplus/cplusplus.pri b/src/shared/cplusplus/cplusplus.pri index 041aff67be..3a62ed6b7d 100644 --- a/src/shared/cplusplus/cplusplus.pri +++ b/src/shared/cplusplus/cplusplus.pri @@ -36,8 +36,8 @@ HEADERS += \ $$PWD/TranslationUnit.h \ $$PWD/Type.h \ $$PWD/TypeVisitor.h \ - $$PWD/PrettyPrinter.h - + $$PWD/PrettyPrinter.h \ + $$PWD/ObjectiveCTypeQualifiers.h SOURCES += \ $$PWD/AST.cpp \ @@ -55,6 +55,7 @@ SOURCES += \ $$PWD/FullySpecifiedType.cpp \ $$PWD/Keywords.cpp \ $$PWD/ObjectiveCAtKeywords.cpp \ + $$PWD/ObjectiveCTypeQualifiers.cpp \ $$PWD/Lexer.cpp \ $$PWD/LiteralTable.cpp \ $$PWD/Literals.cpp \ |
