r181553 - C++1y n3648: parse and reject init-captures for now.
Richard Smith
richard-llvm at metafoo.co.uk
Thu May 9 14:36:42 PDT 2013
Author: rsmith
Date: Thu May 9 16:36:41 2013
New Revision: 181553
URL: http://llvm.org/viewvc/llvm-project?rev=181553&view=rev
Log:
C++1y n3648: parse and reject init-captures for now.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Sema/DeclSpec.h
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Sema/SemaLambda.cpp
cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp
cfe/trunk/test/Parser/objcxx0x-lambda-expressions.mm
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=181553&r1=181552&r2=181553&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu May 9 16:36:41 2013
@@ -4887,6 +4887,8 @@ let CategoryName = "Lambda Issue" in {
def note_lambda_to_block_conv : Note<
"implicit capture of lambda object due to conversion to block pointer "
"here">;
+ def err_lambda_init_capture_unsupported : Error<
+ "sorry, initialized lambda-captures are not supported yet">;
}
def err_return_in_captured_stmt : Error<
Modified: cfe/trunk/include/clang/Sema/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=181553&r1=181552&r2=181553&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Sema/DeclSpec.h Thu May 9 16:36:41 2013
@@ -2088,13 +2088,15 @@ private:
struct LambdaCapture {
LambdaCaptureKind Kind;
SourceLocation Loc;
- IdentifierInfo* Id;
+ IdentifierInfo *Id;
SourceLocation EllipsisLoc;
-
+ ExprResult Init;
+
LambdaCapture(LambdaCaptureKind Kind, SourceLocation Loc,
IdentifierInfo* Id = 0,
- SourceLocation EllipsisLoc = SourceLocation())
- : Kind(Kind), Loc(Loc), Id(Id), EllipsisLoc(EllipsisLoc)
+ SourceLocation EllipsisLoc = SourceLocation(),
+ ExprResult Init = ExprResult())
+ : Kind(Kind), Loc(Loc), Id(Id), EllipsisLoc(EllipsisLoc), Init(Init)
{}
};
@@ -2111,11 +2113,11 @@ struct LambdaIntroducer {
/// \brief Append a capture in a lambda introducer.
void addCapture(LambdaCaptureKind Kind,
SourceLocation Loc,
- IdentifierInfo* Id = 0,
- SourceLocation EllipsisLoc = SourceLocation()) {
- Captures.push_back(LambdaCapture(Kind, Loc, Id, EllipsisLoc));
+ IdentifierInfo* Id = 0,
+ SourceLocation EllipsisLoc = SourceLocation(),
+ ExprResult Init = ExprResult()) {
+ Captures.push_back(LambdaCapture(Kind, Loc, Id, EllipsisLoc, Init));
}
-
};
} // end namespace clang
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=181553&r1=181552&r2=181553&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Thu May 9 16:36:41 2013
@@ -583,7 +583,7 @@ ExprResult Parser::ParseCXXIdExpression(
Tok.is(tok::l_paren), isAddressOfOperand);
}
-/// ParseLambdaExpression - Parse a C++0x lambda expression.
+/// ParseLambdaExpression - Parse a C++11 lambda expression.
///
/// lambda-expression:
/// lambda-introducer lambda-declarator[opt] compound-statement
@@ -605,10 +605,18 @@ ExprResult Parser::ParseCXXIdExpression(
/// capture-list ',' capture
///
/// capture:
+/// simple-capture
+/// init-capture [C++1y]
+///
+/// simple-capture:
/// identifier
/// '&' identifier
/// 'this'
///
+/// init-capture: [C++1y]
+/// identifier initializer
+/// '&' identifier initializer
+///
/// lambda-declarator:
/// '(' parameter-declaration-clause ')' attribute-specifier[opt]
/// 'mutable'[opt] exception-specification[opt]
@@ -737,6 +745,7 @@ Optional<unsigned> Parser::ParseLambdaIn
SourceLocation Loc;
IdentifierInfo* Id = 0;
SourceLocation EllipsisLoc;
+ ExprResult Init;
if (Tok.is(tok::kw_this)) {
Kind = LCK_This;
@@ -768,9 +777,31 @@ Optional<unsigned> Parser::ParseLambdaIn
} else {
return DiagResult(diag::err_expected_capture);
}
+
+ if (Tok.is(tok::l_paren)) {
+ BalancedDelimiterTracker Parens(*this, tok::l_paren);
+ Parens.consumeOpen();
+
+ ExprVector Exprs;
+ CommaLocsTy Commas;
+ if (ParseExpressionList(Exprs, Commas)) {
+ Parens.skipToEnd();
+ Init = ExprError();
+ } else {
+ Parens.consumeClose();
+ Init = Actions.ActOnParenListExpr(Parens.getOpenLocation(),
+ Parens.getCloseLocation(),
+ Exprs);
+ }
+ } else if (Tok.is(tok::l_brace) || Tok.is(tok::equal)) {
+ if (Tok.is(tok::equal))
+ ConsumeToken();
+
+ Init = ParseInitializer();
+ }
}
- Intro.addCapture(Kind, Loc, Id, EllipsisLoc);
+ Intro.addCapture(Kind, Loc, Id, EllipsisLoc, Init);
}
T.consumeClose();
@@ -806,6 +837,9 @@ ExprResult Parser::ParseLambdaExpression
PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), LambdaBeginLoc,
"lambda expression parsing");
+ // FIXME: Call into Actions to add any init-capture declarations to the
+ // scope while parsing the lambda-declarator and compound-statement.
+
// Parse lambda-declarator[opt].
DeclSpec DS(AttrFactory);
Declarator D(DS, Declarator::LambdaExprContext);
Modified: cfe/trunk/lib/Sema/SemaLambda.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=181553&r1=181552&r2=181553&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLambda.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLambda.cpp Thu May 9 16:36:41 2013
@@ -559,6 +559,14 @@ void Sema::ActOnStartOfLambdaDefinition(
continue;
}
+ // FIXME: C++1y [expr.prim.lambda]p11
+ if (C->Init.isInvalid())
+ continue;
+ if (C->Init.isUsable()) {
+ Diag(C->Loc, diag::err_lambda_init_capture_unsupported);
+ continue;
+ }
+
assert(C->Id && "missing identifier for capture");
// C++11 [expr.prim.lambda]p8:
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=181553&r1=181552&r2=181553&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp (original)
+++ cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp Thu May 9 16:36:41 2013
@@ -48,4 +48,22 @@ class C {
delete [] { return new int; } (); // expected-error{{expected expression}}
delete [&] { return new int; } (); // ok, lambda
}
+
+ // We support init-captures in C++11 as an extension.
+ int z;
+ void init_capture() {
+ // FIXME: These diagnostics should all disappear once semantic analysis
+ // for init-captures is complete.
+ [n(0)] () -> int { return ++n; }; // expected-error {{not supported}} expected-error {{undeclared}}
+ [n{0}] { return; }; // expected-error {{not supported}}
+ [n = 0] { return ++n; }; // expected-error {{not supported}} expected-error {{undeclared}}
+ [n = {0}] { return; }; // expected-error {{not supported}}
+ [a([&b = z]{})](){}; // expected-error 2{{not supported}}
+
+ int x = 4; // expected-note {{here}}
+ auto y = [&r = x, x = x + 1]() -> int { // expected-error 2{{not supported}} expected-note {{here}}
+ r += 2; // expected-error {{undeclared}}
+ return x + 2; // expected-error {{implicitly captured}}
+ } ();
+ }
};
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=181553&r1=181552&r2=181553&view=diff
==============================================================================
--- cfe/trunk/test/Parser/objcxx0x-lambda-expressions.mm (original)
+++ cfe/trunk/test/Parser/objcxx0x-lambda-expressions.mm Thu May 9 16:36:41 2013
@@ -17,6 +17,16 @@ class C {
[foo,bar] () { return 3; };
[=,&foo] () {};
[this] () {};
+
+ [foo(bar)] () {}; // expected-error {{not supported}}
+ [foo = bar] () {}; // expected-error {{not supported}}
+ [foo{bar}] () {}; // expected-error {{not supported}}
+ [foo = {bar}] () {}; // expected-error {{not supported}}
+
+ [foo(bar) baz] () {}; // expected-error {{called object type 'int' is not a function}}
+
+ // FIXME: These are some appalling diagnostics.
+ [foo = bar baz]; // expected-error {{missing '['}} expected-warning 2{{receiver type 'int'}} expected-warning 2{{instance method '-baz'}}
}
};
More information about the cfe-commits
mailing list