forked from OSchip/llvm-project
C++1y n3648: parse and reject init-captures for now.
llvm-svn: 181553
This commit is contained in:
parent
8039fdf48c
commit
21b3ab43e1
|
@ -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<
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -583,7 +583,7 @@ ExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {
|
|||
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(bool isAddressOfOperand) {
|
|||
/// 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::ParseLambdaIntroducer(LambdaIntroducer &Intro) {
|
|||
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::ParseLambdaIntroducer(LambdaIntroducer &Intro) {
|
|||
} 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::ParseLambdaExpressionAfterIntroducer(
|
|||
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);
|
||||
|
|
|
@ -559,6 +559,14 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
|
|||
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:
|
||||
|
|
|
@ -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}}
|
||||
} ();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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'}}
|
||||
}
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue