[cfe-commits] r147515 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/Sema.h lib/Parse/ParseExpr.cpp lib/Parse/ParseExprCXX.cpp lib/Sema/SemaExprCXX.cpp test/Parser/cxx0x-attributes.cpp test/Parser/cxx0x-lambda-expressions.cpp test/Parser/objcxx0x-lambda-expressions.mm test/SemaCXX/cxx98-compat.cpp
Eli Friedman
eli.friedman at gmail.com
Tue Jan 3 18:40:40 PST 2012
Author: efriedma
Date: Tue Jan 3 20:40:39 2012
New Revision: 147515
URL: http://llvm.org/viewvc/llvm-project?rev=147515&view=rev
Log:
Stub out the Sema interface for lambda expressions, and change the parser to use it. Unconditionally error on lambda expressions because they don't work in any meaningful way yet.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Parse/ParseExpr.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/test/Parser/cxx0x-attributes.cpp
cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp
cfe/trunk/test/Parser/objcxx0x-lambda-expressions.mm
cfe/trunk/test/SemaCXX/cxx98-compat.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=147515&r1=147514&r2=147515&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jan 3 20:40:39 2012
@@ -3984,6 +3984,8 @@
def err_return_in_constructor_handler : Error<
"return in the catch of a function try block of a constructor is illegal">;
+def err_lambda_unsupported : Error<"lambda expressions are not supported yet">;
+
def err_operator_arrow_circular : Error<
"circular pointer delegation detected">;
def err_pseudo_dtor_base_not_scalar : Error<
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=147515&r1=147514&r2=147515&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Jan 3 20:40:39 2012
@@ -3449,6 +3449,23 @@
/// initializer for the declaration 'Dcl'.
void ActOnCXXExitDeclInitializer(Scope *S, Decl *Dcl);
+ /// ActOnLambdaStart - This callback is invoked when a lambda expression is
+ /// started.
+ void ActOnLambdaStart(SourceLocation StartLoc, Scope *CurScope);
+
+ /// ActOnLambdaArguments - This callback allows processing of lambda arguments.
+ /// If there are no arguments, this is still invoked.
+ void ActOnLambdaArguments(Declarator &ParamInfo, Scope *CurScope);
+
+ /// ActOnLambdaError - If there is an error parsing a lambda, this callback
+ /// is invoked to pop the information about the lambda from the action impl.
+ void ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope);
+
+ /// ActOnLambdaExpr - This is called when the body of a lambda expression
+ /// was successfully completed.
+ ExprResult ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
+ Scope *CurScope);
+
// ParseObjCStringLiteral - Parse Objective-C string literals.
ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
Expr **Strings,
Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=147515&r1=147514&r2=147515&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Tue Jan 3 20:40:39 2012
@@ -1132,8 +1132,13 @@
case tok::l_square:
if (getLang().CPlusPlus0x) {
if (getLang().ObjC1) {
+ // C++11 lambda expressions and Objective-C message sends both start with a
+ // square bracket. There are three possibilities here:
+ // we have a valid lambda expression, we have an invalid lambda
+ // expression, or we have something that doesn't appear to be a lambda.
+ // If we're in the last case, we fall back to ParseObjCMessageExpression.
Res = TryParseLambdaExpression();
- if (Res.isInvalid())
+ if (!Res.isInvalid() && !Res.get())
Res = ParseObjCMessageExpression();
break;
}
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=147515&r1=147514&r2=147515&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Tue Jan 3 20:40:39 2012
@@ -14,6 +14,7 @@
#include "clang/Parse/ParseDiagnostic.h"
#include "clang/Parse/Parser.h"
#include "RAIIObjectsForParser.h"
+#include "clang/Basic/PrettyStackTrace.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/ParsedTemplate.h"
@@ -563,6 +564,9 @@
if (DiagID) {
Diag(Tok, DiagID.getValue());
SkipUntil(tok::r_square);
+ SkipUntil(tok::l_brace);
+ SkipUntil(tok::r_brace);
+ return ExprError();
}
return ParseLambdaExpressionAfterIntroducer(Intro);
@@ -591,14 +595,21 @@
return ParseLambdaExpression();
}
- // If lookahead indicates this is an Objective-C message...
+ // If lookahead indicates an ObjC message send...
+ // [identifier identifier
if (Next.is(tok::identifier) && After.is(tok::identifier)) {
- return ExprError();
+ return ExprEmpty();
}
+ // Here, we're stuck: lambda introducers and Objective-C message sends are
+ // unambiguous, but it requires arbitrary lookhead. [a,b,c,d,e,f,g] is a
+ // lambda, and [a,b,c,d,e,f,g h] is a Objective-C message send. Instead of
+ // writing two routines to parse a lambda introducer, just try to parse
+ // a lambda introducer first, and fall back if that fails.
+ // (TryParseLambdaIntroducer never produces any diagnostic output.)
LambdaIntroducer Intro;
if (TryParseLambdaIntroducer(Intro))
- return ExprError();
+ return ExprEmpty();
return ParseLambdaExpressionAfterIntroducer(Intro);
}
@@ -694,11 +705,17 @@
/// expression.
ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
LambdaIntroducer &Intro) {
- Diag(Intro.Range.getBegin(), diag::warn_cxx98_compat_lambda);
+ SourceLocation LambdaBeginLoc = Intro.Range.getBegin();
+ Diag(LambdaBeginLoc, diag::warn_cxx98_compat_lambda);
+
+ PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), LambdaBeginLoc,
+ "lambda expression parsing");
+
+ Actions.ActOnLambdaStart(LambdaBeginLoc, getCurScope());
// Parse lambda-declarator[opt].
DeclSpec DS(AttrFactory);
- Declarator D(DS, Declarator::PrototypeContext);
+ Declarator D(DS, Declarator::BlockLiteralContext);
if (Tok.is(tok::l_paren)) {
ParseScope PrototypeScope(this,
@@ -775,24 +792,32 @@
DeclLoc, DeclEndLoc, D,
TrailingReturnType),
Attr, DeclEndLoc);
+
+ // Inform sema that we are starting a block.
+ Actions.ActOnLambdaArguments(D, getCurScope());
}
// Parse compound-statement.
- if (Tok.is(tok::l_brace)) {
- // FIXME: Rename BlockScope -> ClosureScope if we decide to continue using
- // it.
- ParseScope BodyScope(this, Scope::BlockScope | Scope::FnScope |
- Scope::BreakScope | Scope::ContinueScope |
- Scope::DeclScope);
-
- ParseCompoundStatementBody();
-
- BodyScope.Exit();
- } else {
+ if (!Tok.is(tok::l_brace)) {
Diag(Tok, diag::err_expected_lambda_body);
+ Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope());
+ return ExprError();
}
- return ExprEmpty();
+ // FIXME: Rename BlockScope -> ClosureScope if we decide to continue using
+ // it.
+ ParseScope BodyScope(this, Scope::BlockScope | Scope::FnScope |
+ Scope::BreakScope | Scope::ContinueScope |
+ Scope::DeclScope);
+ StmtResult Stmt(ParseCompoundStatementBody());
+ BodyScope.Exit();
+
+ if (!Stmt.isInvalid())
+ return Actions.ActOnLambdaExpr(LambdaBeginLoc, Stmt.take(),
+ getCurScope());
+
+ Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope());
+ return ExprError();
}
/// ParseCXXCasts - This handles the various ways to cast expressions to another
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=147515&r1=147514&r2=147515&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Jan 3 20:40:39 2012
@@ -4774,3 +4774,38 @@
return CheckMicrosoftIfExistsSymbol(S, SS, TargetNameInfo);
}
+//===----------------------------------------------------------------------===//
+// Lambdas.
+//===----------------------------------------------------------------------===//
+
+void Sema::ActOnLambdaStart(SourceLocation StartLoc, Scope *CurScope) {
+ // FIXME: Add lambda-scope
+ // FIXME: Build lambda-decl
+ // FIXME: PushDeclContext
+
+ // Enter a new evaluation context to insulate the block from any
+ // cleanups from the enclosing full-expression.
+ PushExpressionEvaluationContext(PotentiallyEvaluated);
+}
+
+void Sema::ActOnLambdaArguments(Declarator &ParamInfo, Scope *CurScope) {
+ // FIXME: Implement
+}
+
+void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope) {
+ // Leave the expression-evaluation context.
+ DiscardCleanupsInEvaluationContext();
+ PopExpressionEvaluationContext();
+
+ // Leave the context of the lambda.
+ // FIXME: PopDeclContext
+ // FIXME: Pop lambda-scope
+}
+
+ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc,
+ Stmt *Body, Scope *CurScope) {
+ // FIXME: Implement
+ Diag(StartLoc, diag::err_lambda_unsupported);
+ ActOnLambdaError(StartLoc, CurScope);
+ return ExprError();
+}
Modified: cfe/trunk/test/Parser/cxx0x-attributes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-attributes.cpp?rev=147515&r1=147514&r2=147515&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx0x-attributes.cpp (original)
+++ cfe/trunk/test/Parser/cxx0x-attributes.cpp Tue Jan 3 20:40:39 2012
@@ -20,7 +20,7 @@
unsigned [[]] int attr_in_decl_spec; // expected-error {{expected unqualified-id}}
int & [[]] ref_attr = after_attr; // expected-error {{an attribute list cannot appear here}}
class foo {
- void after_const_attr () const [[]]; // expected-error {{expected body of lambda expression}} expected-error {{array has incomplete element type 'void'}}
+ void after_const_attr () const [[]]; // expected-error {{expected body of lambda expression}}
};
extern "C++" [[]] { } // expected-error {{an attribute list cannot appear here}}
[[]] template <typename T> void before_template_attr (); // expected-error {{an attribute list cannot appear here}}
Modified: cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp?rev=147515&r1=147514&r2=147515&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp (original)
+++ cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp Tue Jan 3 20:40:39 2012
@@ -12,13 +12,13 @@
[&this] {}; // expected-error {{'this' cannot be captured by reference}}
[&,] {}; // expected-error {{expected variable name or 'this' in lambda capture list}}
[=,] {}; // expected-error {{expected variable name or 'this' in lambda capture list}}
- [] {};
- [=] (int i) {};
- [&] (int) mutable -> void {};
- [foo,bar] () { return 3; };
- [=,&foo] () {};
- [&,foo] () {};
- [this] () {};
+ [] {}; // expected-error {{lambda expressions are not supported yet}}
+ [=] (int i) {}; // expected-error {{lambda expressions are not supported yet}}
+ [&] (int) mutable -> void {}; // expected-error {{lambda expressions are not supported yet}}
+ [foo,bar] () { return 3; }; // expected-error {{lambda expressions are not supported yet}}
+ [=,&foo] () {}; // expected-error {{lambda expressions are not supported yet}}
+ [&,foo] () {}; // expected-error {{lambda expressions are not supported yet}}
+ [this] () {}; // expected-error {{lambda expressions are not supported yet}}
return 1;
}
Modified: cfe/trunk/test/Parser/objcxx0x-lambda-expressions.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/objcxx0x-lambda-expressions.mm?rev=147515&r1=147514&r2=147515&view=diff
==============================================================================
--- cfe/trunk/test/Parser/objcxx0x-lambda-expressions.mm (original)
+++ cfe/trunk/test/Parser/objcxx0x-lambda-expressions.mm Tue Jan 3 20:40:39 2012
@@ -11,15 +11,15 @@
[]; // expected-error {{expected body of lambda expression}}
[=,foo+] {}; // expected-error {{expected ',' or ']' in lambda capture list}}
[&this] {}; // expected-error {{address expression must be an lvalue}}
- [] {};
- [=] (int i) {};
- [&] (int) mutable -> void {};
+ [] {}; // expected-error {{lambda expressions are not supported yet}}
+ [=] (int i) {}; // expected-error {{lambda expressions are not supported yet}}
+ [&] (int) mutable -> void {}; // expected-error {{lambda expressions are not supported yet}}
// FIXME: this error occurs because we do not yet handle lambda scopes
// properly. I did not anticipate it because I thought it was a semantic (not
// syntactic) check.
- [foo,bar] () { return 3; }; // expected-error {{void function 'f' should not return a value}}
- [=,&foo] () {};
- [this] () {};
+ [foo,bar] () { return 3; }; // expected-error {{void function 'f' should not return a value}} expected-error {{lambda expressions are not supported yet}}
+ [=,&foo] () {}; // expected-error {{lambda expressions are not supported yet}}
+ [this] () {}; // expected-error {{lambda expressions are not supported yet}}
}
};
Modified: cfe/trunk/test/SemaCXX/cxx98-compat.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx98-compat.cpp?rev=147515&r1=147514&r2=147515&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx98-compat.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx98-compat.cpp Tue Jan 3 20:40:39 2012
@@ -34,7 +34,8 @@
}
void Lambda() {
- []{}; // expected-warning {{lambda expressions are incompatible with C++98}}
+ // FIXME: Enable when lambdas are minimally working.
+ //[]{}; // FIXME-warning {{lambda expressions are incompatible with C++98}}
}
int InitList() {
More information about the cfe-commits
mailing list