forked from qt-creator/qt-creator
Introduced ForeachStatementAST and the bits to parse foreach statements when qtMocRun is enabled.
This commit is contained in:
@@ -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
|
||||
{
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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 *) { }
|
||||
|
||||
@@ -101,6 +101,7 @@ class ExpressionAST;
|
||||
class ExpressionListAST;
|
||||
class ExpressionOrDeclarationStatementAST;
|
||||
class ExpressionStatementAST;
|
||||
class ForeachStatementAST;
|
||||
class ForStatementAST;
|
||||
class FunctionDeclaratorAST;
|
||||
class FunctionDefinitionAST;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user