summaryrefslogtreecommitdiff
path: root/src/shared/cplusplus
diff options
context:
space:
mode:
authorRoberto Raggi <roberto.raggi@nokia.com>2009-07-03 09:11:52 +0200
committerRoberto Raggi <roberto.raggi@nokia.com>2009-07-03 09:12:58 +0200
commit3cdd48067c8c865d050a19766948d05c86ec6e40 (patch)
tree339702b3a68d8703f87ab01b79cfb5f4894eb54c /src/shared/cplusplus
parent16286b763d74b5793cf1b564252510d4a43ad71f (diff)
downloadqt-creator-3cdd48067c8c865d050a19766948d05c86ec6e40.tar.gz
Introduced ForeachStatementAST and the bits to parse foreach statements when qtMocRun is enabled.
Diffstat (limited to 'src/shared/cplusplus')
-rw-r--r--src/shared/cplusplus/AST.cpp18
-rw-r--r--src/shared/cplusplus/AST.h32
-rw-r--r--src/shared/cplusplus/ASTClone.cpp17
-rw-r--r--src/shared/cplusplus/ASTVisit.cpp15
-rw-r--r--src/shared/cplusplus/ASTVisitor.h2
-rw-r--r--src/shared/cplusplus/ASTfwd.h1
-rw-r--r--src/shared/cplusplus/CheckDeclaration.cpp2
-rw-r--r--src/shared/cplusplus/CheckStatement.cpp29
-rw-r--r--src/shared/cplusplus/CheckStatement.h1
-rw-r--r--src/shared/cplusplus/Control.h2
-rw-r--r--src/shared/cplusplus/Keywords.cpp22
-rw-r--r--src/shared/cplusplus/Parser.cpp46
-rw-r--r--src/shared/cplusplus/Parser.h1
-rw-r--r--src/shared/cplusplus/Semantic.cpp2
-rw-r--r--src/shared/cplusplus/Token.h7
15 files changed, 183 insertions, 14 deletions
diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp
index c809f6e1d0..dc6a505677 100644
--- a/src/shared/cplusplus/AST.cpp
+++ b/src/shared/cplusplus/AST.cpp
@@ -874,6 +874,24 @@ unsigned ExpressionStatementAST::lastToken() const
return 0;
}
+unsigned ForeachStatementAST::firstToken() const
+{
+ return foreach_token;
+}
+
+unsigned ForeachStatementAST::lastToken() const
+{
+ if (statement)
+ return statement->lastToken();
+ else if (rparen_token)
+ return rparen_token + 1;
+ else if (expression)
+ return expression->lastToken();
+ else if (comma_token)
+ return comma_token + 1;
+
+ return foreach_token + 1;
+}
unsigned ForStatementAST::firstToken() const
{
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index f345fd76b0..d22735eeb1 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -131,6 +131,7 @@ public:
virtual ExpressionListAST *asExpressionList() { return 0; }
virtual ExpressionOrDeclarationStatementAST *asExpressionOrDeclarationStatement() { return 0; }
virtual ExpressionStatementAST *asExpressionStatement() { return 0; }
+ virtual ForeachStatementAST *asForeachStatement() { return 0; }
virtual ForStatementAST *asForStatement() { return 0; }
virtual FunctionDeclaratorAST *asFunctionDeclarator() { return 0; }
virtual FunctionDefinitionAST *asFunctionDefinition() { return 0; }
@@ -1135,6 +1136,37 @@ protected:
virtual void accept0(ASTVisitor *visitor);
};
+class CPLUSPLUS_EXPORT ForeachStatementAST: public StatementAST
+{
+public:
+ unsigned foreach_token;
+ unsigned lparen_token;
+ // declaration
+ SpecifierAST *type_specifiers;
+ DeclaratorAST *declarator;
+ // or an expression
+ ExpressionAST *initializer;
+ unsigned comma_token;
+ ExpressionAST *expression;
+ unsigned rparen_token;
+ StatementAST *statement;
+
+public: // annotations
+ Block *symbol;
+
+public:
+ virtual ForeachStatementAST *asForeachStatement()
+ { return this; }
+
+ virtual unsigned firstToken() const;
+ virtual unsigned lastToken() const;
+
+ virtual ForeachStatementAST *clone(MemoryPool *pool) const;
+
+protected:
+ virtual void accept0(ASTVisitor *visitor);
+};
+
class CPLUSPLUS_EXPORT ForStatementAST: public StatementAST
{
public:
diff --git a/src/shared/cplusplus/ASTClone.cpp b/src/shared/cplusplus/ASTClone.cpp
index c3eb1ab40f..2e446c89ef 100644
--- a/src/shared/cplusplus/ASTClone.cpp
+++ b/src/shared/cplusplus/ASTClone.cpp
@@ -514,6 +514,23 @@ FunctionDefinitionAST *FunctionDefinitionAST::clone(MemoryPool *pool) const
return ast;
}
+ForeachStatementAST *ForeachStatementAST::clone(MemoryPool *pool) const
+{
+ ForeachStatementAST *ast = new (pool) ForeachStatementAST;
+ // copy StatementAST
+ // copy ForeachStatementAST
+ ast->foreach_token = foreach_token;
+ ast->lparen_token = lparen_token;
+ if (type_specifiers) ast->type_specifiers = type_specifiers->clone(pool);
+ if (declarator) ast->declarator = declarator->clone(pool);
+ if (initializer) ast->initializer = initializer->clone(pool);
+ ast->comma_token = comma_token;
+ if (expression) ast->expression = expression->clone(pool);
+ ast->rparen_token = rparen_token;
+ if (statement) ast->statement = statement->clone(pool);
+ return ast;
+}
+
ForStatementAST *ForStatementAST::clone(MemoryPool *pool) const
{
ForStatementAST *ast = new (pool) ForStatementAST;
diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp
index c85ce39707..1673577474 100644
--- a/src/shared/cplusplus/ASTVisit.cpp
+++ b/src/shared/cplusplus/ASTVisit.cpp
@@ -474,6 +474,21 @@ void FunctionDefinitionAST::accept0(ASTVisitor *visitor)
visitor->endVisit(this);
}
+void ForeachStatementAST::accept0(ASTVisitor *visitor)
+{
+ if (visitor->visit(this)) {
+ // visit ForeachStatementAST
+ for (SpecifierAST *it = type_specifiers; it; it = it->next)
+ accept(it, visitor);
+ accept(declarator, visitor);
+ accept(initializer, visitor);
+ accept(expression, visitor);
+ accept(statement, visitor);
+ // visit StatementAST
+ }
+ visitor->endVisit(this);
+}
+
void ForStatementAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h
index 45c8d89efc..caa93e5e1b 100644
--- a/src/shared/cplusplus/ASTVisitor.h
+++ b/src/shared/cplusplus/ASTVisitor.h
@@ -134,6 +134,7 @@ public:
virtual bool visit(ExpressionListAST *) { return true; }
virtual bool visit(ExpressionOrDeclarationStatementAST *) { return true; }
virtual bool visit(ExpressionStatementAST *) { return true; }
+ virtual bool visit(ForeachStatementAST *) { return true; }
virtual bool visit(ForStatementAST *) { return true; }
virtual bool visit(FunctionDeclaratorAST *) { return true; }
virtual bool visit(FunctionDefinitionAST *) { return true; }
@@ -242,6 +243,7 @@ public:
virtual void endVisit(ExpressionListAST *) { }
virtual void endVisit(ExpressionOrDeclarationStatementAST *) { }
virtual void endVisit(ExpressionStatementAST *) { }
+ virtual void endVisit(ForeachStatementAST *) { }
virtual void endVisit(ForStatementAST *) { }
virtual void endVisit(FunctionDeclaratorAST *) { }
virtual void endVisit(FunctionDefinitionAST *) { }
diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h
index 0f4d9581bf..ee5f8e876f 100644
--- a/src/shared/cplusplus/ASTfwd.h
+++ b/src/shared/cplusplus/ASTfwd.h
@@ -101,6 +101,7 @@ class ExpressionAST;
class ExpressionListAST;
class ExpressionOrDeclarationStatementAST;
class ExpressionStatementAST;
+class ForeachStatementAST;
class ForStatementAST;
class FunctionDeclaratorAST;
class FunctionDefinitionAST;
diff --git a/src/shared/cplusplus/CheckDeclaration.cpp b/src/shared/cplusplus/CheckDeclaration.cpp
index 038d70b9a4..1bd8086cdb 100644
--- a/src/shared/cplusplus/CheckDeclaration.cpp
+++ b/src/shared/cplusplus/CheckDeclaration.cpp
@@ -251,7 +251,7 @@ bool CheckDeclaration::visit(AccessDeclarationAST *ast)
semantic()->switchVisibility(visibility);
if (ast->slots_token)
semantic()->switchMethodKey(Function::SlotMethod);
- else if (accessSpecifier == T_SIGNALS)
+ else if (accessSpecifier == T_Q_SIGNALS)
semantic()->switchMethodKey(Function::SignalMethod);
else
semantic()->switchMethodKey(Function::NormalMethod);
diff --git a/src/shared/cplusplus/CheckStatement.cpp b/src/shared/cplusplus/CheckStatement.cpp
index 0d7bced86e..c93eca0492 100644
--- a/src/shared/cplusplus/CheckStatement.cpp
+++ b/src/shared/cplusplus/CheckStatement.cpp
@@ -141,6 +141,35 @@ bool CheckStatement::visit(ExpressionStatementAST *ast)
return false;
}
+bool CheckStatement::visit(ForeachStatementAST *ast)
+{
+ Block *block = control()->newBlock(ast->foreach_token);
+ block->setStartOffset(tokenAt(ast->firstToken()).offset);
+ block->setEndOffset(tokenAt(ast->lastToken()).offset);
+ ast->symbol = block;
+ _scope->enterSymbol(block);
+ Scope *previousScope = switchScope(block->members());
+ if (ast->type_specifiers && ast->declarator) {
+ FullySpecifiedType ty = semantic()->check(ast->type_specifiers, _scope);
+ Name *name = 0;
+ ty = semantic()->check(ast->declarator, ty, _scope, &name);
+ unsigned location = ast->declarator->firstToken();
+ if (CoreDeclaratorAST *core_declarator = ast->declarator->core_declarator)
+ location = core_declarator->firstToken();
+ Declaration *decl = control()->newDeclaration(location, name);
+ decl->setType(ty);
+ _scope->enterSymbol(decl);
+ } else {
+ FullySpecifiedType exprTy = semantic()->check(ast->initializer, _scope);
+ (void) exprTy;
+ }
+
+ FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope);
+ semantic()->check(ast->statement, _scope);
+ (void) switchScope(previousScope);
+ return false;
+}
+
bool CheckStatement::visit(ForStatementAST *ast)
{
Block *block = control()->newBlock(ast->for_token);
diff --git a/src/shared/cplusplus/CheckStatement.h b/src/shared/cplusplus/CheckStatement.h
index 59b74b1363..baa2bdccf3 100644
--- a/src/shared/cplusplus/CheckStatement.h
+++ b/src/shared/cplusplus/CheckStatement.h
@@ -75,6 +75,7 @@ protected:
virtual bool visit(DoStatementAST *ast);
virtual bool visit(ExpressionOrDeclarationStatementAST *ast);
virtual bool visit(ExpressionStatementAST *ast);
+ virtual bool visit(ForeachStatementAST *ast);
virtual bool visit(ForStatementAST *ast);
virtual bool visit(IfStatementAST *ast);
virtual bool visit(LabeledStatementAST *ast);
diff --git a/src/shared/cplusplus/Control.h b/src/shared/cplusplus/Control.h
index b06063d4f5..8b4f09afff 100644
--- a/src/shared/cplusplus/Control.h
+++ b/src/shared/cplusplus/Control.h
@@ -115,7 +115,7 @@ public:
NamedType *namedType(Name *name);
/// Creates a new Declaration symbol.
- Declaration *newDeclaration(unsigned sourceLocation, Name *name = 0);
+ Declaration *newDeclaration(unsigned sourceLocation, Name *name);
/// Creates a new Argument symbol.
Argument *newArgument(unsigned sourceLocation, Name *name = 0);
diff --git a/src/shared/cplusplus/Keywords.cpp b/src/shared/cplusplus/Keywords.cpp
index e1b605668a..e26244a0af 100644
--- a/src/shared/cplusplus/Keywords.cpp
+++ b/src/shared/cplusplus/Keywords.cpp
@@ -297,7 +297,7 @@ static inline int classify5(const char *s, bool q) {
if (s[2] == 'o') {
if (s[3] == 't') {
if (s[4] == 's') {
- return T_SLOTS;
+ return T_Q_SLOTS;
}
}
}
@@ -627,7 +627,7 @@ static inline int classify7(const char *s, bool q) {
if (s[4] == 'a') {
if (s[5] == 'l') {
if (s[6] == 's') {
- return T_SIGNALS;
+ return T_Q_SIGNALS;
}
}
}
@@ -687,7 +687,7 @@ static inline int classify7(const char *s, bool q) {
if (s[4] == 'O') {
if (s[5] == 'T') {
if (s[6] == 'S') {
- return T_SLOTS;
+ return T_Q_SLOTS;
}
}
}
@@ -950,7 +950,21 @@ static inline int classify9(const char *s, bool q) {
if (s[6] == 'A') {
if (s[7] == 'L') {
if (s[8] == 'S') {
- return T_SIGNALS;
+ return T_Q_SIGNALS;
+ }
+ }
+ }
+ }
+ }
+ }
+ } else if (s[2] == 'F') {
+ if (s[3] == 'O') {
+ if (s[4] == 'R') {
+ if (s[5] == 'E') {
+ if (s[6] == 'A') {
+ if (s[7] == 'C') {
+ if (s[8] == 'H') {
+ return T_Q_FOREACH;
}
}
}
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index 08266e9f79..dba11df713 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -1464,11 +1464,11 @@ bool Parser::parseAccessSpecifier(SpecifierAST *&node)
bool Parser::parseAccessDeclaration(DeclarationAST *&node)
{
- if (LA() == T_PUBLIC || LA() == T_PROTECTED || LA() == T_PRIVATE || LA() == T_SIGNALS) {
- bool isSignals = LA() == T_SIGNALS;
+ if (LA() == T_PUBLIC || LA() == T_PROTECTED || LA() == T_PRIVATE || LA() == T_Q_SIGNALS) {
+ bool isSignals = LA() == T_Q_SIGNALS;
AccessDeclarationAST *ast = new (_pool) AccessDeclarationAST;
ast->access_specifier_token = consumeToken();
- if (! isSignals && LA() == T_SLOTS)
+ if (! isSignals && LA() == T_Q_SLOTS)
ast->slots_token = consumeToken();
match(T_COLON, &ast->colon_token);
node = ast;
@@ -1489,7 +1489,7 @@ bool Parser::parseMemberSpecification(DeclarationAST *&node)
case T_TEMPLATE:
return parseTemplateDeclaration(node);
- case T_SIGNALS:
+ case T_Q_SIGNALS:
case T_PUBLIC:
case T_PROTECTED:
case T_PRIVATE:
@@ -1861,6 +1861,9 @@ bool Parser::parseStatement(StatementAST *&node)
case T_DO:
return parseDoStatement(node);
+ case T_Q_FOREACH:
+ return parseForeachStatement(node);
+
case T_FOR:
return parseForStatement(node);
@@ -2108,6 +2111,41 @@ bool Parser::parseDoStatement(StatementAST *&node)
return false;
}
+bool Parser::parseForeachStatement(StatementAST *&node)
+{
+ if (LA() == T_Q_FOREACH) {
+ ForeachStatementAST *ast = new (_pool) ForeachStatementAST;
+ ast->foreach_token = consumeToken();
+ match(T_LPAREN, &ast->lparen_token);
+
+ unsigned startOfTypeSpecifier = cursor();
+ bool blocked = blockErrors(true);
+
+ if (parseTypeSpecifier(ast->type_specifiers))
+ parseDeclarator(ast->declarator);
+
+ if (! ast->type_specifiers || ! ast->declarator) {
+ ast->type_specifiers = 0;
+ ast->declarator = 0;
+
+ blockErrors(blocked);
+ rewind(startOfTypeSpecifier);
+ parseExpression(ast->expression);
+ }
+
+ blockErrors(blocked);
+
+ match(T_COMMA, &ast->comma_token);
+ parseExpression(ast->expression);
+ match(T_RPAREN, &ast->rparen_token);
+ parseStatement(ast->statement);
+
+ node = ast;
+ return true;
+ }
+ return false;
+}
+
bool Parser::parseForStatement(StatementAST *&node)
{
if (LA() == T_FOR) {
diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h
index 330bb84b3d..c5515b05ec 100644
--- a/src/shared/cplusplus/Parser.h
+++ b/src/shared/cplusplus/Parser.h
@@ -121,6 +121,7 @@ public:
bool parseExpressionOrDeclarationStatement(StatementAST *&node);
bool parseExpressionStatement(StatementAST *&node);
bool parseForInitStatement(StatementAST *&node);
+ bool parseForeachStatement(StatementAST *&node);
bool parseForStatement(StatementAST *&node);
bool parseFunctionBody(StatementAST *&node);
bool parseIfStatement(StatementAST *&node);
diff --git a/src/shared/cplusplus/Semantic.cpp b/src/shared/cplusplus/Semantic.cpp
index 9e7108bbc5..6f44072302 100644
--- a/src/shared/cplusplus/Semantic.cpp
+++ b/src/shared/cplusplus/Semantic.cpp
@@ -179,7 +179,7 @@ int Semantic::visibilityForAccessSpecifier(int tokenKind) const
return Symbol::Protected;
case T_PRIVATE:
return Symbol::Private;
- case T_SIGNALS:
+ case T_Q_SIGNALS:
return Symbol::Protected;
default:
return Symbol::Public;
diff --git a/src/shared/cplusplus/Token.h b/src/shared/cplusplus/Token.h
index 660e91e4b6..6774dba336 100644
--- a/src/shared/cplusplus/Token.h
+++ b/src/shared/cplusplus/Token.h
@@ -234,10 +234,11 @@ enum Kind {
T_SLOT,
T_Q_SIGNAL,
T_Q_SLOT,
- T_SIGNALS,
- T_SLOTS,
+ T_Q_SIGNALS,
+ T_Q_SLOTS,
+ T_Q_FOREACH,
- T_LAST_KEYWORD = T_SLOTS,
+ T_LAST_KEYWORD = T_Q_FOREACH,
// aliases
T_OR = T_PIPE_PIPE,