Commit 8329d7db authored by Roberto Raggi's avatar Roberto Raggi
Browse files

Recognize C++0x lambda expressions.

parent 35be3a9f
......@@ -123,6 +123,7 @@ Document::Document(const QString &fileName)
localFileName.size());
_translationUnit = new TranslationUnit(_control, fileId);
_translationUnit->setQtMocRunEnabled(true);
_translationUnit->setCxxOxEnabled(true);
_translationUnit->setObjCEnabled(true);
(void) _control->switchTranslationUnit(_translationUnit);
}
......
......@@ -2416,3 +2416,119 @@ unsigned ObjCSynchronizedStatementAST::lastToken() const
if (lparen_token) return lparen_token + 1;
return synchronized_token + 1;
}
unsigned LambdaExpressionAST::firstToken() const
{
if (lambda_introducer)
return lambda_introducer->firstToken();
// assert?
return 0;
}
unsigned LambdaExpressionAST::lastToken() const
{
if (statement)
return statement->lastToken();
else if (lambda_declarator)
return lambda_declarator->lastToken();
return lambda_introducer->lastToken();
}
unsigned LambdaIntroducerAST::firstToken() const
{
return lbracket_token;
}
unsigned LambdaIntroducerAST::lastToken() const
{
if (rbracket_token)
return rbracket_token + 1;
else if (lambda_capture)
return lambda_capture->lastToken();
return lbracket_token + 1;
}
unsigned LambdaCaptureAST::firstToken() const
{
if (default_capture)
return default_capture;
else if (capture_list)
return capture_list->firstToken();
// assert?
return 0;
}
unsigned LambdaCaptureAST::lastToken() const
{
if (capture_list)
return capture_list->lastToken();
else if (default_capture)
return default_capture + 1;
// assert?
return 0;
}
unsigned CaptureAST::firstToken() const
{
// ### implement me
return 0;
}
unsigned CaptureAST::lastToken() const
{
// ### implement me
return 0;
}
unsigned LambdaDeclaratorAST::firstToken() const
{
return lparen_token;
}
unsigned LambdaDeclaratorAST::lastToken() const
{
if (trailing_return_type)
return trailing_return_type->lastToken();
else if (exception_specification)
return exception_specification->lastToken();
else if (mutable_token)
return mutable_token + 1;
else if (attributes)
return attributes->lastToken();
else if (rparen_token)
return rparen_token + 1;
else if (parameter_declaration_clause)
return parameter_declaration_clause->lastToken();
return lparen_token + 1;
}
unsigned TrailingReturnTypeAST::firstToken() const
{
return arrow_token;
}
unsigned TrailingReturnTypeAST::lastToken() const
{
if (declarator)
return declarator->lastToken();
else if (type_specifiers)
return type_specifiers->lastToken();
else if (attributes)
return attributes->lastToken();
return arrow_token + 1;
}
......@@ -164,6 +164,7 @@ public:
virtual BoolLiteralAST *asBoolLiteral() { return 0; }
virtual BreakStatementAST *asBreakStatement() { return 0; }
virtual CallAST *asCall() { return 0; }
virtual CaptureAST *asCapture() { return 0; }
virtual CaseStatementAST *asCaseStatement() { return 0; }
virtual CastExpressionAST *asCastExpression() { return 0; }
virtual CatchClauseAST *asCatchClause() { return 0; }
......@@ -201,6 +202,10 @@ public:
virtual GotoStatementAST *asGotoStatement() { return 0; }
virtual IfStatementAST *asIfStatement() { return 0; }
virtual LabeledStatementAST *asLabeledStatement() { return 0; }
virtual LambdaCaptureAST *asLambdaCapture() { return 0; }
virtual LambdaDeclaratorAST *asLambdaDeclarator() { return 0; }
virtual LambdaExpressionAST *asLambdaExpression() { return 0; }
virtual LambdaIntroducerAST *asLambdaIntroducer() { return 0; }
virtual LinkageBodyAST *asLinkageBody() { return 0; }
virtual LinkageSpecificationAST *asLinkageSpecification() { return 0; }
virtual MemInitializerAST *asMemInitializer() { return 0; }
......@@ -280,6 +285,7 @@ public:
virtual TemplateTypeParameterAST *asTemplateTypeParameter() { return 0; }
virtual ThisExpressionAST *asThisExpression() { return 0; }
virtual ThrowExpressionAST *asThrowExpression() { return 0; }
virtual TrailingReturnTypeAST *asTrailingReturnType() { return 0; }
virtual TranslationUnitAST *asTranslationUnit() { return 0; }
virtual TryBlockStatementAST *asTryBlockStatement() { return 0; }
virtual TypeConstructorCallAST *asTypeConstructorCall() { return 0; }
......@@ -4103,7 +4109,157 @@ protected:
virtual bool match0(AST *, ASTMatcher *);
};
} // end of namespace CPlusPlus
class LambdaExpressionAST: public ExpressionAST
{
public:
LambdaIntroducerAST *lambda_introducer;
LambdaDeclaratorAST *lambda_declarator;
StatementAST *statement;
public:
LambdaExpressionAST()
: lambda_introducer(0)
, lambda_declarator(0)
, statement(0)
{}
virtual LambdaExpressionAST *asLambdaExpression() { return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
virtual LambdaExpressionAST *clone(MemoryPool *pool) const;
protected:
virtual void accept0(ASTVisitor *visitor);
virtual bool match0(AST *, ASTMatcher *);
};
class LambdaIntroducerAST: public AST
{
public:
unsigned lbracket_token;
LambdaCaptureAST *lambda_capture;
unsigned rbracket_token;
public:
LambdaIntroducerAST()
: lbracket_token(0)
, lambda_capture(0)
, rbracket_token(0)
{}
virtual LambdaIntroducerAST *asLambdaIntroducer() { return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
virtual LambdaIntroducerAST *clone(MemoryPool *pool) const;
protected:
virtual void accept0(ASTVisitor *visitor);
virtual bool match0(AST *, ASTMatcher *);
};
class LambdaCaptureAST: public AST
{
public:
unsigned default_capture;
CaptureListAST *capture_list;
public:
LambdaCaptureAST()
: default_capture(0)
, capture_list(0)
{}
virtual LambdaCaptureAST *asLambdaCapture() { return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
virtual LambdaCaptureAST *clone(MemoryPool *pool) const;
protected:
virtual void accept0(ASTVisitor *visitor);
virtual bool match0(AST *, ASTMatcher *);
};
class CaptureAST: public AST
{
public:
CaptureAST()
{}
virtual CaptureAST *asCapture() { return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
virtual CaptureAST *clone(MemoryPool *pool) const;
protected:
virtual void accept0(ASTVisitor *visitor);
virtual bool match0(AST *, ASTMatcher *);
};
class LambdaDeclaratorAST: public AST
{
public:
unsigned lparen_token;
ParameterDeclarationClauseAST *parameter_declaration_clause;
unsigned rparen_token;
SpecifierListAST *attributes;
unsigned mutable_token;
ExceptionSpecificationAST *exception_specification;
TrailingReturnTypeAST *trailing_return_type;
public:
LambdaDeclaratorAST()
: lparen_token(0)
, parameter_declaration_clause(0)
, rparen_token(0)
, attributes(0)
, mutable_token(0)
, exception_specification(0)
, trailing_return_type(0)
{}
virtual LambdaDeclaratorAST *asLambdaDeclarator() { return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
virtual LambdaDeclaratorAST *clone(MemoryPool *pool) const;
protected:
virtual void accept0(ASTVisitor *visitor);
virtual bool match0(AST *, ASTMatcher *);
};
class TrailingReturnTypeAST: public AST
{
public:
unsigned arrow_token;
SpecifierListAST *attributes;
SpecifierListAST *type_specifiers;
DeclaratorAST *declarator;
public:
TrailingReturnTypeAST()
: arrow_token(0)
, attributes(0)
, type_specifiers(0)
, declarator(0)
{}
virtual TrailingReturnTypeAST *asTrailingReturnType() { return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
virtual TrailingReturnTypeAST *clone(MemoryPool *pool) const;
protected:
virtual void accept0(ASTVisitor *visitor);
virtual bool match0(AST *, ASTMatcher *);
};
} // end of namespace CPlusPlus
#endif // CPLUSPLUS_AST_H
......@@ -1586,3 +1586,73 @@ ObjCSynchronizedStatementAST *ObjCSynchronizedStatementAST::clone(MemoryPool *po
return ast;
}
LambdaExpressionAST *LambdaExpressionAST::clone(MemoryPool *pool) const
{
LambdaExpressionAST *ast = new (pool) LambdaExpressionAST;
if (lambda_introducer)
ast->lambda_introducer = lambda_introducer->clone(pool);
if (lambda_declarator)
ast->lambda_declarator = lambda_declarator->clone(pool);
if (statement)
ast->statement = statement->clone(pool);
return ast;
}
LambdaIntroducerAST *LambdaIntroducerAST::clone(MemoryPool *pool) const
{
LambdaIntroducerAST *ast = new (pool) LambdaIntroducerAST;
ast->lbracket_token = lbracket_token;
if (lambda_capture)
ast->lambda_capture = lambda_capture->clone(pool);
ast->rbracket_token = rbracket_token;
return ast;
}
LambdaCaptureAST *LambdaCaptureAST::clone(MemoryPool *pool) const
{
LambdaCaptureAST *ast = new (pool) LambdaCaptureAST;
for (CaptureListAST *iter = capture_list, **ast_iter = &ast->capture_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
*ast_iter = new (pool) CaptureListAST((iter->value) ? iter->value->clone(pool) : 0);
return ast;
}
CaptureAST *CaptureAST::clone(MemoryPool *pool) const
{
CaptureAST *ast = new (pool) CaptureAST;
return ast;
}
LambdaDeclaratorAST *LambdaDeclaratorAST::clone(MemoryPool *pool) const
{
LambdaDeclaratorAST *ast = new (pool) LambdaDeclaratorAST;
ast->lparen_token = lparen_token;
if (parameter_declaration_clause)
ast->parameter_declaration_clause = parameter_declaration_clause->clone(pool);
ast->rparen_token = rparen_token;
for (SpecifierListAST *iter = attributes, **ast_iter = &ast->attributes;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
*ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
ast->mutable_token = mutable_token;
if (exception_specification)
ast->exception_specification = exception_specification->clone(pool);
if (trailing_return_type)
ast->trailing_return_type = trailing_return_type->clone(pool);
return ast;
}
TrailingReturnTypeAST *TrailingReturnTypeAST::clone(MemoryPool *pool) const
{
TrailingReturnTypeAST *ast = new (pool) TrailingReturnTypeAST;
ast->arrow_token = arrow_token;
for (SpecifierListAST *iter = attributes, **ast_iter = &ast->attributes;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
*ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
for (SpecifierListAST *iter = type_specifiers, **ast_iter = &ast->type_specifiers;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
*ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
if (declarator)
ast->declarator = declarator->clone(pool);
return ast;
}
......@@ -1089,3 +1089,51 @@ bool ObjCSynchronizedStatementAST::match0(AST *pattern, ASTMatcher *matcher)
return false;
}
bool LambdaExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (LambdaExpressionAST *_other = pattern->asLambdaExpression())
return matcher->match(this, _other);
return false;
}
bool LambdaIntroducerAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (LambdaIntroducerAST *_other = pattern->asLambdaIntroducer())
return matcher->match(this, _other);
return false;
}
bool LambdaCaptureAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (LambdaCaptureAST *_other = pattern->asLambdaCapture())
return matcher->match(this, _other);
return false;
}
bool CaptureAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (CaptureAST *_other = pattern->asCapture())
return matcher->match(this, _other);
return false;
}
bool LambdaDeclaratorAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (LambdaDeclaratorAST *_other = pattern->asLambdaDeclarator())
return matcher->match(this, _other);
return false;
}
bool TrailingReturnTypeAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (TrailingReturnTypeAST *_other = pattern->asTrailingReturnType())
return matcher->match(this, _other);
return false;
}
......@@ -2669,3 +2669,123 @@ bool ASTMatcher::match(ObjCSynchronizedStatementAST *node, ObjCSynchronizedState
return true;
}
bool ASTMatcher::match(LambdaExpressionAST *node, LambdaExpressionAST *pattern)
{
(void) node;
(void) pattern;
if (! pattern->lambda_introducer)
pattern->lambda_introducer = node->lambda_introducer;
else if (! AST::match(node->lambda_introducer, pattern->lambda_introducer, this))
return false;
if (! pattern->lambda_declarator)
pattern->lambda_declarator = node->lambda_declarator;
else if (! AST::match(node->lambda_declarator, pattern->lambda_declarator, this))
return false;
if (! pattern->statement)
pattern->statement = node->statement;
else if (! AST::match(node->statement, pattern->statement, this))
return false;
return true;
}
bool ASTMatcher::match(LambdaIntroducerAST *node, LambdaIntroducerAST *pattern)
{
(void) node;
(void) pattern;
pattern->lbracket_token = node->lbracket_token;
if (! pattern->lambda_capture)
pattern->lambda_capture = node->lambda_capture;
else if (! AST::match(node->lambda_capture, pattern->lambda_capture, this))
return false;
pattern->rbracket_token = node->rbracket_token;
return true;
}
bool ASTMatcher::match(LambdaCaptureAST *node, LambdaCaptureAST *pattern)
{
(void) node;
(void) pattern;
if (! pattern->capture_list)
pattern->capture_list = node->capture_list;
else if (! AST::match(node->capture_list, pattern->capture_list, this))
return false;
return true;
}
bool ASTMatcher::match(CaptureAST *node, CaptureAST *pattern)
{
(void) node;
(void) pattern;
return true;
}
bool ASTMatcher::match(LambdaDeclaratorAST *node, LambdaDeclaratorAST *pattern)
{
(void) node;
(void) pattern;
pattern->lparen_token = node->lparen_token;
if (! pattern->parameter_declaration_clause)
pattern->parameter_declaration_clause = node->parameter_declaration_clause;
else if (! AST::match(node->parameter_declaration_clause, pattern->parameter_declaration_clause, this))
return false;
pattern->rparen_token = node->rparen_token;
if (! pattern->attributes)
pattern->attributes = node->attributes;
else if (! AST::match(node->attributes, pattern->attributes, this))
return false;
pattern->mutable_token = node->mutable_token;
if (! pattern->exception_specification)
pattern->exception_specification = node->exception_specification;
else if (! AST::match(node->exception_specification, pattern->exception_specification, this))
return false;
if (! pattern->trailing_return_type)
pattern->trailing_return_type = node->trailing_return_type;
else if (! AST::match(node->trailing_return_type, pattern->trailing_return_type, this))
return false;
return true;
}
bool ASTMatcher::match(TrailingReturnTypeAST *node, TrailingReturnTypeAST *pattern)
{
(void) node;
(void) pattern;
pattern->arrow_token = node->arrow_token;
if (! pattern->attributes)
pattern->attributes = node->attributes;
else if (! AST::match(node->attributes, pattern->attributes, this))
return false;
if (! pattern->type_specifiers)
pattern->type_specifiers = node->type_specifiers;
else if (! AST::match(node->type_specifiers, pattern->type_specifiers, this))
return false;
if (! pattern->declarator)
pattern->declarator = node->declarator;
else if (! AST::match(node->declarator, pattern->declarator, this))
return false;
return true;
}
......@@ -170,6 +170,12 @@ public:
virtual bool match(ObjCDynamicPropertiesDeclarationAST *node, ObjCDynamicPropertiesDeclarationAST *pattern);
virtual bool match(ObjCFastEnumerationAST *node, ObjCFastEnumerationAST *pattern);
virtual bool match(ObjCSynchronizedStatementAST *node, ObjCSynchronizedStatementAST *pattern);
virtual bool match(LambdaExpressionAST *node, LambdaExpressionAST *pattern);
virtual bool match(LambdaIntroducerAST *node, LambdaIntroducerAST *pattern);
virtual bool match(LambdaCaptureAST *node, LambdaCaptureAST *pattern);
virtual bool match(LambdaDeclaratorAST *node, LambdaDeclaratorAST *pattern);
virtual bool match(CaptureAST *node, CaptureAST *pattern);
virtual bool match(TrailingReturnTypeAST *node, TrailingReturnTypeAST *pattern);
};
} // end of namespace CPlusPlus
......
......@@ -1159,3 +1159,57 @@ void ObjCSynchronizedStatementAST::accept0(ASTVisitor *visitor)
visitor->endVisit(this);
}
void LambdaExpressionAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
accept(lambda_introducer, visitor);
accept(lambda_declarator, visitor);
accept(statement, visitor);
}
visitor->endVisit(this);
}