summaryrefslogtreecommitdiff
path: root/src/shared/cplusplus
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared/cplusplus')
-rw-r--r--src/shared/cplusplus/AST.cpp116
-rw-r--r--src/shared/cplusplus/AST.h158
-rw-r--r--src/shared/cplusplus/ASTClone.cpp70
-rw-r--r--src/shared/cplusplus/ASTMatch0.cpp48
-rw-r--r--src/shared/cplusplus/ASTMatcher.cpp120
-rw-r--r--src/shared/cplusplus/ASTMatcher.h6
-rw-r--r--src/shared/cplusplus/ASTVisit.cpp54
-rw-r--r--src/shared/cplusplus/ASTVisitor.h15
-rw-r--r--src/shared/cplusplus/ASTfwd.h8
-rw-r--r--src/shared/cplusplus/CheckExpression.cpp11
-rw-r--r--src/shared/cplusplus/CheckExpression.h1
-rw-r--r--src/shared/cplusplus/Keywords.cpp62
-rw-r--r--src/shared/cplusplus/Lexer.cpp8
-rw-r--r--src/shared/cplusplus/Lexer.h6
-rw-r--r--src/shared/cplusplus/Parser.cpp181
-rw-r--r--src/shared/cplusplus/Parser.h10
-rw-r--r--src/shared/cplusplus/TranslationUnit.cpp8
-rw-r--r--src/shared/cplusplus/TranslationUnit.h4
18 files changed, 849 insertions, 37 deletions
diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp
index 785b8178d4..7677180455 100644
--- a/src/shared/cplusplus/AST.cpp
+++ b/src/shared/cplusplus/AST.cpp
@@ -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;
+}
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index 11f038db5a..6335fce4ba 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -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
diff --git a/src/shared/cplusplus/ASTClone.cpp b/src/shared/cplusplus/ASTClone.cpp
index 586d88e21a..425c81c76e 100644
--- a/src/shared/cplusplus/ASTClone.cpp
+++ b/src/shared/cplusplus/ASTClone.cpp
@@ -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;
+}
+
diff --git a/src/shared/cplusplus/ASTMatch0.cpp b/src/shared/cplusplus/ASTMatch0.cpp
index 0b97e9c7fa..bc2f252b81 100644
--- a/src/shared/cplusplus/ASTMatch0.cpp
+++ b/src/shared/cplusplus/ASTMatch0.cpp
@@ -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;
+}
+
diff --git a/src/shared/cplusplus/ASTMatcher.cpp b/src/shared/cplusplus/ASTMatcher.cpp
index 42cbadcbdb..75ec26467d 100644
--- a/src/shared/cplusplus/ASTMatcher.cpp
+++ b/src/shared/cplusplus/ASTMatcher.cpp
@@ -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;
+}
+
diff --git a/src/shared/cplusplus/ASTMatcher.h b/src/shared/cplusplus/ASTMatcher.h
index baae1ce874..d3fcab5dcf 100644
--- a/src/shared/cplusplus/ASTMatcher.h
+++ b/src/shared/cplusplus/ASTMatcher.h
@@ -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
diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp
index 8216f87b48..9e3b249ef3 100644
--- a/src/shared/cplusplus/ASTVisit.cpp
+++ b/src/shared/cplusplus/ASTVisit.cpp
@@ -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);
+}
+
+void LambdaIntroducerAST::accept0(ASTVisitor *visitor)
+{
+ if (visitor->visit(this)) {
+ accept(lambda_capture, visitor);
+ }
+ visitor->endVisit(this);
+}
+
+void LambdaCaptureAST::accept0(ASTVisitor *visitor)
+{
+ if (visitor->visit(this)) {
+ accept(capture_list, visitor);
+ }
+ visitor->endVisit(this);
+}
+
+void CaptureAST::accept0(ASTVisitor *visitor)
+{
+ if (visitor->visit(this)) {
+ }
+ visitor->endVisit(this);
+}
+
+void LambdaDeclaratorAST::accept0(ASTVisitor *visitor)
+{
+ if (visitor->visit(this)) {
+ accept(parameter_declaration_clause, visitor);
+ accept(attributes, visitor);
+ accept(exception_specification, visitor);
+ accept(trailing_return_type, visitor);
+ }
+ visitor->endVisit(this);
+}
+
+void TrailingReturnTypeAST::accept0(ASTVisitor *visitor)
+{
+ if (visitor->visit(this)) {
+ accept(attributes, visitor);
+ accept(type_specifiers, visitor);
+ accept(declarator, visitor);
+ }
+ visitor->endVisit(this);
+}
+
diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h
index 4490f11faa..078dfee89e 100644
--- a/src/shared/cplusplus/ASTVisitor.h
+++ b/src/shared/cplusplus/ASTVisitor.h
@@ -209,6 +209,14 @@ public:
virtual bool visit(QtInterfacesDeclarationAST *) { return true; }
virtual bool visit(QtInterfaceNameAST *) { return true; }
+ // C++0x
+ virtual bool visit(LambdaExpressionAST *) { return true; }
+ virtual bool visit(LambdaIntroducerAST *) { return true; }
+ virtual bool visit(LambdaCaptureAST *) { return true; }
+ virtual bool visit(LambdaDeclaratorAST *) { return true; }
+ virtual bool visit(CaptureAST *) { return true; }
+ virtual bool visit(TrailingReturnTypeAST *) { return true; }
+
// ObjC++
virtual bool visit(ObjCClassDeclarationAST *) { return true; }
virtual bool visit(ObjCClassForwardDeclarationAST *) { return true; }
@@ -343,6 +351,13 @@ public:
virtual void endVisit(QtInterfacesDeclarationAST *) { }
virtual void endVisit(QtInterfaceNameAST *) { }
+ virtual void endVisit(LambdaExpressionAST *) { }
+ virtual void endVisit(LambdaIntroducerAST *) { }
+ virtual void endVisit(LambdaCaptureAST *) { }
+ virtual void endVisit(LambdaDeclaratorAST *) { }
+ virtual void endVisit(CaptureAST *) { }
+ virtual void endVisit(TrailingReturnTypeAST *) { }
+
// ObjC++
virtual void endVisit(ObjCClassDeclarationAST *) { }
virtual void endVisit(ObjCClassForwardDeclarationAST *) { }
diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h
index f8f129acb4..ac6006256b 100644
--- a/src/shared/cplusplus/ASTfwd.h
+++ b/src/shared/cplusplus/ASTfwd.h
@@ -71,6 +71,7 @@ class BinaryExpressionAST;
class BoolLiteralAST;
class BreakStatementAST;
class CallAST;
+class CaptureAST;
class CaseStatementAST;
class CastExpressionAST;
class CatchClauseAST;
@@ -108,6 +109,10 @@ class FunctionDefinitionAST;
class GotoStatementAST;
class IfStatementAST;
class LabeledStatementAST;
+class LambdaCaptureAST;
+class LambdaDeclaratorAST;
+class LambdaExpressionAST;
+class LambdaIntroducerAST;
class LinkageBodyAST;
class LinkageSpecificationAST;
class MemInitializerAST;
@@ -187,6 +192,7 @@ class TemplateIdAST;
class TemplateTypeParameterAST;
class ThisExpressionAST;
class ThrowExpressionAST;
+class TrailingReturnTypeAST;
class TranslationUnitAST;
class TryBlockStatementAST;
class TypeConstructorCallAST;
@@ -219,6 +225,8 @@ typedef List<QtPropertyDeclarationItemAST *> QtPropertyDeclarationItemListAST;
typedef List<NameAST *> NameListAST;
typedef List<QtInterfaceNameAST *> QtInterfaceNameListAST;
+typedef List<CaptureAST *> CaptureListAST;
+
typedef List<ObjCMessageArgumentAST *> ObjCMessageArgumentListAST;
typedef List<ObjCSelectorArgumentAST *> ObjCSelectorArgumentListAST;
typedef List<ObjCPropertyAttributeAST *> ObjCPropertyAttributeListAST;
diff --git a/src/shared/cplusplus/CheckExpression.cpp b/src/shared/cplusplus/CheckExpression.cpp
index ecbf991c9a..42f1d85a71 100644
--- a/src/shared/cplusplus/CheckExpression.cpp
+++ b/src/shared/cplusplus/CheckExpression.cpp
@@ -388,8 +388,19 @@ bool CheckExpression::visit(ObjCEncodeExpressionAST * /*ast*/)
bool CheckExpression::visit(ObjCSelectorExpressionAST *ast)
{
+ if (_scope->isPrototypeScope())
+ return false;
+
(void) semantic()->check(ast->selector, _scope);
return false;
}
+bool CheckExpression::visit(LambdaExpressionAST *ast)
+{
+ if (_scope->isPrototypeScope())
+ return false;
+
+ (void) semantic()->check(ast->statement, _scope);
+ return false;
+}
diff --git a/src/shared/cplusplus/CheckExpression.h b/src/shared/cplusplus/CheckExpression.h
index 6485d1236d..736eefa0ed 100644
--- a/src/shared/cplusplus/CheckExpression.h
+++ b/src/shared/cplusplus/CheckExpression.h
@@ -95,6 +95,7 @@ protected:
virtual bool visit(QtMethodAST *ast);
virtual bool visit(CompoundLiteralAST *ast);
virtual bool visit(CompoundExpressionAST *ast);
+ virtual bool visit(LambdaExpressionAST *ast);
//names
virtual bool visit(QualifiedNameAST *ast);
diff --git a/src/shared/cplusplus/Keywords.cpp b/src/shared/cplusplus/Keywords.cpp
index 0e6beaf06f..94699c1745 100644
--- a/src/shared/cplusplus/Keywords.cpp
+++ b/src/shared/cplusplus/Keywords.cpp
@@ -51,7 +51,7 @@
using namespace CPlusPlus;
-static inline int classify2(const char *s, bool) {
+static inline int classify2(const char *s, bool, bool) {
if (s[0] == 'd') {
if (s[1] == 'o') {
return T_DO;
@@ -65,7 +65,7 @@ static inline int classify2(const char *s, bool) {
return T_IDENTIFIER;
}
-static inline int classify3(const char *s, bool q) {
+static inline int classify3(const char *s, bool q, bool) {
if (s[0] == 'a') {
if (s[1] == 's') {
if (s[2] == 'm') {
@@ -114,7 +114,7 @@ static inline int classify3(const char *s, bool q) {
return T_IDENTIFIER;
}
-static inline int classify4(const char *s, bool q) {
+static inline int classify4(const char *s, bool q, bool) {
if (s[0] == 'a') {
if (s[1] == 'u') {
if (s[2] == 't') {
@@ -220,7 +220,7 @@ static inline int classify4(const char *s, bool q) {
return T_IDENTIFIER;
}
-static inline int classify5(const char *s, bool q) {
+static inline int classify5(const char *s, bool q, bool) {
if (s[0] == '_') {
if (s[1] == '_') {
if (s[2] == 'a') {
@@ -359,7 +359,7 @@ static inline int classify5(const char *s, bool q) {
return T_IDENTIFIER;
}
-static inline int classify6(const char *s, bool q) {
+static inline int classify6(const char *s, bool q, bool) {
if (s[0] == 'd') {
if (s[1] == 'e') {
if (s[2] == 'l') {
@@ -558,7 +558,7 @@ static inline int classify6(const char *s, bool q) {
return T_IDENTIFIER;
}
-static inline int classify7(const char *s, bool q) {
+static inline int classify7(const char *s, bool q, bool) {
if (s[0] == '_') {
if (s[1] == '_') {
if (s[2] == 'a') {
@@ -745,7 +745,7 @@ static inline int classify7(const char *s, bool q) {
return T_IDENTIFIER;
}
-static inline int classify8(const char *s, bool q) {
+static inline int classify8(const char *s, bool q, bool) {
if (s[0] == '_') {
if (s[1] == '_') {
if (s[2] == 'i') {
@@ -956,7 +956,7 @@ static inline int classify8(const char *s, bool q) {
return T_IDENTIFIER;
}
-static inline int classify9(const char *s, bool q) {
+static inline int classify9(const char *s, bool q, bool) {
if (s[0] == '_') {
if (s[1] == '_') {
if (s[2] == 'c') {
@@ -1050,7 +1050,7 @@ static inline int classify9(const char *s, bool q) {
return T_IDENTIFIER;
}
-static inline int classify10(const char *s, bool q) {
+static inline int classify10(const char *s, bool q, bool) {
if (s[0] == '_') {
if (s[1] == '_') {
if (s[2] == 'i') {
@@ -1168,7 +1168,7 @@ static inline int classify10(const char *s, bool q) {
return T_IDENTIFIER;
}
-static inline int classify11(const char *s, bool q) {
+static inline int classify11(const char *s, bool q, bool) {
if (s[0] == '_') {
if (s[1] == '_') {
if (s[2] == 'a') {
@@ -1241,7 +1241,7 @@ static inline int classify11(const char *s, bool q) {
return T_IDENTIFIER;
}
-static inline int classify12(const char *s, bool q) {
+static inline int classify12(const char *s, bool q, bool) {
if (s[0] == '_') {
if (s[1] == '_') {
if (s[2] == 'v') {
@@ -1320,7 +1320,7 @@ static inline int classify12(const char *s, bool q) {
return T_IDENTIFIER;
}
-static inline int classify13(const char *s, bool) {
+static inline int classify13(const char *s, bool, bool) {
if (s[0] == '_') {
if (s[1] == '_') {
if (s[2] == 'a') {
@@ -1351,7 +1351,7 @@ static inline int classify13(const char *s, bool) {
return T_IDENTIFIER;
}
-static inline int classify16(const char *s, bool) {
+static inline int classify16(const char *s, bool, bool) {
if (s[0] == 'r') {
if (s[1] == 'e') {
if (s[2] == 'i') {
@@ -1388,7 +1388,7 @@ static inline int classify16(const char *s, bool) {
return T_IDENTIFIER;
}
-static inline int classify14(const char *s, bool q) {
+static inline int classify14(const char *s, bool q, bool) {
if (q && s[0] == 'Q') {
if (s[1] == '_') {
if (s[2] == 'P') {
@@ -1421,7 +1421,7 @@ static inline int classify14(const char *s, bool q) {
return T_IDENTIFIER;
}
-static inline int classify19(const char *s, bool q) {
+static inline int classify19(const char *s, bool q, bool) {
if (q && s[0] == 'Q') {
if (s[1] == '_') {
if (s[2] == 'D') {
@@ -1465,23 +1465,23 @@ static inline int classify19(const char *s, bool q) {
}
-int Lexer::classify(const char *s, int n, bool q) {
+int Lexer::classify(const char *s, int n, bool q, bool x) {
switch (n) {
- case 2: return classify2(s, q);
- case 3: return classify3(s, q);
- case 4: return classify4(s, q);
- case 5: return classify5(s, q);
- case 6: return classify6(s, q);
- case 7: return classify7(s, q);
- case 8: return classify8(s, q);
- case 9: return classify9(s, q);
- case 10: return classify10(s, q);
- case 11: return classify11(s, q);
- case 12: return classify12(s, q);
- case 13: return classify13(s, q);
- case 14: return classify14(s, q);
- case 16: return classify16(s, q);
- case 19: return classify19(s, q);
+ case 2: return classify2(s, q, x);
+ case 3: return classify3(s, q, x);
+ case 4: return classify4(s, q, x);
+ case 5: return classify5(s, q, x);
+ case 6: return classify6(s, q, x);
+ case 7: return classify7(s, q, x);
+ case 8: return classify8(s, q, x);
+ case 9: return classify9(s, q, x);
+ case 10: return classify10(s, q, x);
+ case 11: return classify11(s, q, x);
+ case 12: return classify12(s, q, x);
+ case 13: return classify13(s, q, x);
+ case 14: return classify14(s, q, x);
+ case 16: return classify16(s, q, x);
+ case 19: return classify19(s, q, x);
default: return T_IDENTIFIER;
} // switch
}
diff --git a/src/shared/cplusplus/Lexer.cpp b/src/shared/cplusplus/Lexer.cpp
index 36b2ba8b0b..3b75c68421 100644
--- a/src/shared/cplusplus/Lexer.cpp
+++ b/src/shared/cplusplus/Lexer.cpp
@@ -119,6 +119,12 @@ bool Lexer::qtMocRunEnabled() const
void Lexer::setQtMocRunEnabled(bool onoff)
{ f._qtMocRunEnabled = onoff; }
+bool Lexer::cxx0xEnabled() const
+{ return f._cxx0xEnabled; }
+
+void Lexer::setCxxOxEnabled(bool onoff)
+{ f._cxx0xEnabled = onoff; }
+
bool Lexer::objCEnabled() const
{ return f._objCEnabled; }
@@ -680,7 +686,7 @@ void Lexer::scan_helper(Token *tok)
yyinp();
int yylen = _currentChar - yytext;
if (f._scanKeywords)
- tok->f.kind = classify(yytext, yylen, f._qtMocRunEnabled);
+ tok->f.kind = classify(yytext, yylen, f._qtMocRunEnabled, f._cxx0xEnabled);
else
tok->f.kind = T_IDENTIFIER;
diff --git a/src/shared/cplusplus/Lexer.h b/src/shared/cplusplus/Lexer.h
index 36bb8b1285..f528455452 100644
--- a/src/shared/cplusplus/Lexer.h
+++ b/src/shared/cplusplus/Lexer.h
@@ -77,6 +77,9 @@ public:
bool qtMocRunEnabled() const;
void setQtMocRunEnabled(bool onoff);
+ bool cxx0xEnabled() const;
+ void setCxxOxEnabled(bool onoff);
+
bool objCEnabled() const;
void setObjCEnabled(bool onoff);
@@ -111,7 +114,7 @@ public:
private:
void scan_helper(Token *tok);
void setSource(const char *firstChar, const char *lastChar);
- static int classify(const char *string, int length, bool q);
+ static int classify(const char *string, int length, bool q, bool cxx0x);
static int classifyObjCAtKeyword(const char *s, int n);
static int classifyOperator(const char *string, int length);
@@ -135,6 +138,7 @@ private:
unsigned _scanKeywords: 1;
unsigned _scanAngleStringLiteralTokens: 1;
unsigned _qtMocRunEnabled: 1;
+ unsigned _cxx0xEnabled: 1;
unsigned _objCEnabled: 1;
};
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index 7be7e61dab..d5c55a2c35 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -197,7 +197,7 @@ Parser::Parser(TranslationUnit *unit)
_tokenIndex(1),
_templateArguments(0),
_qtMocRunEnabled(false),
- _cxx0xEnabled(true), // C++0x is enabled by default
+ _cxx0xEnabled(false),
_objCEnabled(false),
_inFunctionBody(false),
_inObjCImplementationContext(false),
@@ -2524,7 +2524,8 @@ bool Parser::parseExpressionStatement(StatementAST *&node)
ExpressionAST *expression = 0;
if (parseExpression(expression)) {
ExpressionStatementAST *ast = new (previousPool) ExpressionStatementAST;
- ast->expression = expression->clone(previousPool);
+ if (expression)
+ ast->expression = expression->clone(previousPool);
match(T_SEMICOLON, &ast->semicolon_token);
node = ast;
parsed = true;
@@ -3646,7 +3647,20 @@ bool Parser::parsePrimaryExpression(ExpressionAST *&node)
case T_SLOT:
return parseQtMethod(node);
- case T_LBRACKET:
+ case T_LBRACKET: {
+ const unsigned lbracket_token = cursor();
+
+ if (_cxx0xEnabled) {
+ if (parseLambdaExpression(node))
+ return true;
+ }
+
+ if (_objCEnabled) {
+ rewind(lbracket_token);
+ return parseObjCExpression(node);
+ }
+ } break;
+
case T_AT_STRING_LITERAL:
case T_AT_ENCODE:
case T_AT_PROTOCOL:
@@ -5491,3 +5505,164 @@ int Parser::peekAtQtContextKeyword() const
const Identifier *id = tok().identifier;
return classifyQtContextKeyword(id->chars(), id->size());
}
+
+bool Parser::parseLambdaExpression(ExpressionAST *&node)
+{
+ DEBUG_THIS_RULE();
+
+ LambdaIntroducerAST *lambda_introducer = 0;
+ if (parseLambdaIntroducer(lambda_introducer)) {
+ LambdaExpressionAST *ast = new (_pool) LambdaExpressionAST;
+ ast->lambda_introducer = lambda_introducer;
+ parseLambdaDeclarator(ast->lambda_declarator);
+ parseCompoundStatement(ast->statement);
+ node = ast;
+ return true;
+ }
+
+ return false;
+}
+
+bool Parser::parseLambdaIntroducer(LambdaIntroducerAST *&node)
+{
+ DEBUG_THIS_RULE();
+ if (LA() != T_LBRACKET)
+ return false;
+
+ LambdaIntroducerAST *ast = new (_pool) LambdaIntroducerAST;
+ ast->lbracket_token = consumeToken();
+
+ if (LA() != T_RBRACKET)
+ parseLambdaCapture(ast->lambda_capture);
+
+ if (LA() == T_RBRACKET) {
+ ast->rbracket_token = consumeToken();
+
+ if (LA() == T_LPAREN || LA() == T_LBRACE) {
+ node = ast;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool Parser::parseLambdaCapture(LambdaCaptureAST *&node)
+{
+ DEBUG_THIS_RULE();
+ bool startsWithDefaultCapture = false;
+
+ unsigned default_capture = 0;
+ CaptureListAST *capture_list = 0;
+
+ if (LA() == T_AMPER || LA() == T_EQUAL) {
+ if (LA(2) == T_COMMA || LA(2) == T_RBRACKET) {
+ startsWithDefaultCapture = true;
+ default_capture = consumeToken(); // consume capture-default
+ }
+ }
+
+ if (startsWithDefaultCapture && LA() == T_COMMA) {
+ consumeToken(); // consume ','
+ parseCaptureList(capture_list); // required
+
+ } else if (LA() != T_RBRACKET) {
+ parseCaptureList(capture_list); // optional
+
+ }
+
+ LambdaCaptureAST *ast = new (_pool) LambdaCaptureAST;
+ ast->default_capture = default_capture;
+ ast->capture_list = capture_list;
+ node = ast;
+
+ return true;
+}
+
+bool Parser::parseCapture(CaptureAST *&)
+{
+ DEBUG_THIS_RULE();
+ if (LA() == T_IDENTIFIER) {
+ consumeToken();
+ return true;
+
+ } else if (LA() == T_AMPER && LA(2) == T_IDENTIFIER) {
+ consumeToken();
+ consumeToken();
+ return true;
+
+ } else if (LA() == T_THIS) {
+ consumeToken();
+ return true;
+ }
+
+ return false;
+}
+
+bool Parser::parseCaptureList(CaptureListAST *&)
+{
+ DEBUG_THIS_RULE();
+
+ CaptureAST *capture = 0;
+
+ if (parseCapture(capture)) {
+ while (LA() == T_COMMA) {
+ consumeToken(); // consume `,'
+
+ parseCapture(capture);
+ }
+ }
+
+ return true;
+}
+
+bool Parser::parseLambdaDeclarator(LambdaDeclaratorAST *&node)
+{
+ DEBUG_THIS_RULE();
+ if (LA() != T_LPAREN)
+ return false;
+
+ LambdaDeclaratorAST *ast = new (_pool) LambdaDeclaratorAST;
+
+ ast->lparen_token = consumeToken(); // consume `('
+ parseParameterDeclarationClause(ast->parameter_declaration_clause);
+ match(T_RPAREN, &ast->rparen_token);
+
+ SpecifierListAST **attr = &ast->attributes;
+ while (parseAttributeSpecifier(*attr))
+ attr = &(*attr)->next;
+
+ if (LA() == T_MUTABLE)
+ ast->mutable_token = consumeToken();
+
+ parseExceptionSpecification(ast->exception_specification);
+ parseTrailingReturnType(ast->trailing_return_type);
+ node = ast;
+
+ return true;
+}
+
+bool Parser::parseTrailingReturnType(TrailingReturnTypeAST *&node)
+{
+ DEBUG_THIS_RULE();
+ if (LA() != T_ARROW)
+ return false;
+
+ TrailingReturnTypeAST *ast = new (_pool) TrailingReturnTypeAST;
+
+ ast->arrow_token = consumeToken();
+
+ SpecifierListAST **attr = &ast->attributes;
+ while (parseAttributeSpecifier(*attr))
+ attr = &(*attr)->next;
+
+ parseTrailingTypeSpecifierSeq(ast->type_specifiers);
+ parseAbstractDeclarator(ast->declarator);
+ return true;
+}
+
+bool Parser::parseTrailingTypeSpecifierSeq(SpecifierListAST *&node)
+{
+ DEBUG_THIS_RULE();
+ return parseSimpleTypeSpecifier(node);
+}
diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h
index b6f2809837..d31551f187 100644
--- a/src/shared/cplusplus/Parser.h
+++ b/src/shared/cplusplus/Parser.h
@@ -221,6 +221,16 @@ public:
// Qt MOC run
bool parseQtMethod(ExpressionAST *&node);
+ // C++0x
+ bool parseLambdaExpression(ExpressionAST *&node);
+ bool parseLambdaIntroducer(LambdaIntroducerAST *&node);
+ bool parseLambdaCapture(LambdaCaptureAST *&node);
+ bool parseLambdaDeclarator(LambdaDeclaratorAST *&node);
+ bool parseCapture(CaptureAST *&node);
+ bool parseCaptureList(CaptureListAST *&node);
+ bool parseTrailingReturnType(TrailingReturnTypeAST *&node);
+ bool parseTrailingTypeSpecifierSeq(SpecifierListAST *&node);
+
// ObjC++
bool parseObjCExpression(ExpressionAST *&node);
bool parseObjCClassForwardDeclaration(DeclarationAST *&node);
diff --git a/src/shared/cplusplus/TranslationUnit.cpp b/src/shared/cplusplus/TranslationUnit.cpp
index f19b78d851..340b763fc5 100644
--- a/src/shared/cplusplus/TranslationUnit.cpp
+++ b/src/shared/cplusplus/TranslationUnit.cpp
@@ -87,6 +87,12 @@ bool TranslationUnit::qtMocRunEnabled() const
void TranslationUnit::setQtMocRunEnabled(bool onoff)
{ f._qtMocRunEnabled = onoff; }
+bool TranslationUnit::cxx0xEnabled() const
+{ return f._cxx0xEnabled; }
+
+void TranslationUnit::setCxxOxEnabled(bool onoff)
+{ f._cxx0xEnabled = onoff; }
+
bool TranslationUnit::objCEnabled() const
{ return f._objCEnabled; }
@@ -173,6 +179,7 @@ void TranslationUnit::tokenize()
Lexer lex(this);
lex.setQtMocRunEnabled(f._qtMocRunEnabled);
+ lex.setCxxOxEnabled(f._cxx0xEnabled);
lex.setObjCEnabled(f._objCEnabled);
std::stack<unsigned> braces;
@@ -256,6 +263,7 @@ bool TranslationUnit::parse(ParseMode mode)
Parser parser(this);
parser.setQtMocRunEnabled(f._qtMocRunEnabled);
+ parser.setCxxOxEnabled(f._cxx0xEnabled);
parser.setObjCEnabled(f._objCEnabled);
bool parsed = false;
diff --git a/src/shared/cplusplus/TranslationUnit.h b/src/shared/cplusplus/TranslationUnit.h
index 53e11abb9b..19324f6b87 100644
--- a/src/shared/cplusplus/TranslationUnit.h
+++ b/src/shared/cplusplus/TranslationUnit.h
@@ -98,6 +98,9 @@ public:
bool qtMocRunEnabled() const;
void setQtMocRunEnabled(bool onoff);
+ bool cxx0xEnabled() const;
+ void setCxxOxEnabled(bool onoff);
+
bool objCEnabled() const;
void setObjCEnabled(bool onoff);
@@ -195,6 +198,7 @@ private:
unsigned _blockErrors: 1;
unsigned _skipFunctionBody: 1;
unsigned _qtMocRunEnabled: 1;
+ unsigned _cxx0xEnabled: 1;
unsigned _objCEnabled: 1;
};
union {