diff options
author | Faisal Vali <faisalv@yahoo.com> | 2016-03-21 09:25:37 +0000 |
---|---|---|
committer | Faisal Vali <faisalv@yahoo.com> | 2016-03-21 09:25:37 +0000 |
commit | dc6b596ebbd3c594c75fc6c6bc6cb7c14fdcec24 (patch) | |
tree | 22cb8f82b4795afc128f86720b6ca4f148211e8f /clang/lib/Parse/ParseExprCXX.cpp | |
parent | 2c8b5993bebd0b5523e254a06f82322c46f1221b (diff) | |
download | bcm5719-llvm-dc6b596ebbd3c594c75fc6c6bc6cb7c14fdcec24.tar.gz bcm5719-llvm-dc6b596ebbd3c594c75fc6c6bc6cb7c14fdcec24.zip |
[Cxx1z] Implement Lambda Capture of *this by Value as [=,*this] (P0018R3)
Implement lambda capture of *this by copy.
For e.g.:
struct A {
int d = 10;
auto foo() { return [*this] (auto a) mutable { d+=a; return d; }; }
};
auto L = A{}.foo(); // A{}'s lifetime is gone.
// Below is still ok, because *this was captured by value.
assert(L(10) == 20);
assert(L(100) == 120);
If the capture was implicit, or [this] (i.e. *this was captured by reference), this code would be otherwise undefined.
Implementation Strategy:
- amend the parser to accept *this in the lambda introducer
- add a new king of capture LCK_StarThis
- teach Sema::CheckCXXThisCapture to handle by copy captures of the
enclosing object (i.e. *this)
- when CheckCXXThisCapture does capture by copy, the corresponding
initializer expression for the closure's data member
direct-initializes it thus making a copy of '*this'.
- in codegen, when assigning to CXXThisValue, if *this was captured by
copy, make sure it points to the corresponding field member, and
not, unlike when captured by reference, what the field member points
to.
- mark feature as implemented in svn
Much gratitude to Richard Smith for his carefully illuminating reviews!
llvm-svn: 263921
Diffstat (limited to 'clang/lib/Parse/ParseExprCXX.cpp')
-rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 558d2371f6c..8e5f35ad65c 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -846,8 +846,16 @@ Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro, IdentifierInfo *Id = nullptr; SourceLocation EllipsisLoc; ExprResult Init; - - if (Tok.is(tok::kw_this)) { + + if (Tok.is(tok::star)) { + Loc = ConsumeToken(); + if (Tok.is(tok::kw_this)) { + ConsumeToken(); + Kind = LCK_StarThis; + } else { + return DiagResult(diag::err_expected_star_this_capture); + } + } else if (Tok.is(tok::kw_this)) { Kind = LCK_This; Loc = ConsumeToken(); } else { |