aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
authorRichard Smith <richard@metafoo.co.uk>2020-06-04 19:15:22 -0700
committerRichard Smith <richard@metafoo.co.uk>2020-06-04 19:19:01 -0700
commitc13dd74e311d2ac70dd3ea663d800307d1aa5b6b (patch)
tree3ed4b35468c56fd7aacd1201e8cc7ccd0d2b5577 /clang/lib
parent4c735439fd9a0cfea9ae366df8b36281436d4708 (diff)
downloadllvm-c13dd74e311d2ac70dd3ea663d800307d1aa5b6b.zip
llvm-c13dd74e311d2ac70dd3ea663d800307d1aa5b6b.tar.gz
llvm-c13dd74e311d2ac70dd3ea663d800307d1aa5b6b.tar.bz2
Set the captures on a CXXRecordDecl representing a lambda closure type
before marking it complete. No functionality change intended.
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTImporter.cpp32
-rw-r--r--clang/lib/AST/DeclCXX.cpp21
-rw-r--r--clang/lib/AST/ExprCXX.cpp45
-rw-r--r--clang/lib/Sema/SemaLambda.cpp3
4 files changed, 54 insertions, 47 deletions
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 1003516..a2a712e 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -1890,6 +1890,19 @@ Error ASTNodeImporter::ImportDefinition(
// set in CXXRecordDecl::CreateLambda. We must import the contained
// decls here and finish the definition.
(To->isLambda() && shouldForceImportDeclContext(Kind))) {
+ if (To->isLambda()) {
+ auto *FromCXXRD = cast<CXXRecordDecl>(From);
+ SmallVector<LambdaCapture, 8> ToCaptures;
+ ToCaptures.reserve(FromCXXRD->capture_size());
+ for (const auto &FromCapture : FromCXXRD->captures()) {
+ if (auto ToCaptureOrErr = import(FromCapture))
+ ToCaptures.push_back(*ToCaptureOrErr);
+ else
+ return ToCaptureOrErr.takeError();
+ }
+ cast<CXXRecordDecl>(To)->setCaptures(ToCaptures);
+ }
+
Error Result = ImportDeclContext(From, /*ForceImport=*/true);
// Finish the definition of the lambda, set isBeingDefined to false.
if (To->isLambda())
@@ -7588,15 +7601,6 @@ ExpectedStmt ASTNodeImporter::VisitLambdaExpr(LambdaExpr *E) {
if (!ToCallOpOrErr)
return ToCallOpOrErr.takeError();
- SmallVector<LambdaCapture, 8> ToCaptures;
- ToCaptures.reserve(E->capture_size());
- for (const auto &FromCapture : E->captures()) {
- if (auto ToCaptureOrErr = import(FromCapture))
- ToCaptures.push_back(*ToCaptureOrErr);
- else
- return ToCaptureOrErr.takeError();
- }
-
SmallVector<Expr *, 8> ToCaptureInits(E->capture_size());
if (Error Err = ImportContainerChecked(E->capture_inits(), ToCaptureInits))
return std::move(Err);
@@ -7608,11 +7612,11 @@ ExpectedStmt ASTNodeImporter::VisitLambdaExpr(LambdaExpr *E) {
if (Err)
return std::move(Err);
- return LambdaExpr::Create(
- Importer.getToContext(), ToClass, ToIntroducerRange,
- E->getCaptureDefault(), ToCaptureDefaultLoc, ToCaptures,
- E->hasExplicitParameters(), E->hasExplicitResultType(), ToCaptureInits,
- ToEndLoc, E->containsUnexpandedParameterPack());
+ return LambdaExpr::Create(Importer.getToContext(), ToClass, ToIntroducerRange,
+ E->getCaptureDefault(), ToCaptureDefaultLoc,
+ E->hasExplicitParameters(),
+ E->hasExplicitResultType(), ToCaptureInits,
+ ToEndLoc, E->containsUnexpandedParameterPack());
}
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 5412aa7..4d184b5 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -664,8 +664,7 @@ bool CXXRecordDecl::lambdaIsDefaultConstructibleAndAssignable() const {
// C++17 [expr.prim.lambda]p21:
// The closure type associated with a lambda-expression has no default
// constructor and a deleted copy assignment operator.
- if (getLambdaCaptureDefault() != LCD_None ||
- getLambdaData().NumCaptures != 0)
+ if (getLambdaCaptureDefault() != LCD_None || capture_size() != 0)
return false;
return getASTContext().getLangOpts().CPlusPlus20;
}
@@ -1367,6 +1366,24 @@ void CXXRecordDecl::finishedDefaultedOrDeletedMember(CXXMethodDecl *D) {
data().DeclaredNonTrivialSpecialMembers |= SMKind;
}
+void CXXRecordDecl::setCaptures(ArrayRef<LambdaCapture> Captures) {
+ ASTContext &Context = getASTContext();
+ CXXRecordDecl::LambdaDefinitionData &Data = getLambdaData();
+
+ // Copy captures.
+ Data.NumCaptures = Captures.size();
+ Data.NumExplicitCaptures = 0;
+ Data.Captures = (LambdaCapture *)Context.Allocate(sizeof(LambdaCapture) *
+ Captures.size());
+ LambdaCapture *ToCapture = Data.Captures;
+ for (unsigned I = 0, N = Captures.size(); I != N; ++I) {
+ if (Captures[I].isExplicit())
+ ++Data.NumExplicitCaptures;
+
+ *ToCapture++ = Captures[I];
+ }
+}
+
void CXXRecordDecl::setTrivialForCallFlags(CXXMethodDecl *D) {
unsigned SMKind = 0;
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index cfbf2c8..2b148b4 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -1087,35 +1087,18 @@ LambdaCaptureKind LambdaCapture::getCaptureKind() const {
LambdaExpr::LambdaExpr(QualType T, SourceRange IntroducerRange,
LambdaCaptureDefault CaptureDefault,
- SourceLocation CaptureDefaultLoc,
- ArrayRef<LambdaCapture> Captures, bool ExplicitParams,
+ SourceLocation CaptureDefaultLoc, bool ExplicitParams,
bool ExplicitResultType, ArrayRef<Expr *> CaptureInits,
SourceLocation ClosingBrace,
bool ContainsUnexpandedParameterPack)
: Expr(LambdaExprClass, T, VK_RValue, OK_Ordinary),
IntroducerRange(IntroducerRange), CaptureDefaultLoc(CaptureDefaultLoc),
- NumCaptures(Captures.size()), CaptureDefault(CaptureDefault),
+ NumCaptures(CaptureInits.size()), CaptureDefault(CaptureDefault),
ExplicitParams(ExplicitParams), ExplicitResultType(ExplicitResultType),
ClosingBrace(ClosingBrace) {
- assert(CaptureInits.size() == Captures.size() && "Wrong number of arguments");
CXXRecordDecl *Class = getLambdaClass();
- CXXRecordDecl::LambdaDefinitionData &Data = Class->getLambdaData();
-
- // FIXME: Propagate "has unexpanded parameter pack" bit.
-
- // Copy captures.
- const ASTContext &Context = Class->getASTContext();
- Data.NumCaptures = NumCaptures;
- Data.NumExplicitCaptures = 0;
- Data.Captures =
- (LambdaCapture *)Context.Allocate(sizeof(LambdaCapture) * NumCaptures);
- LambdaCapture *ToCapture = Data.Captures;
- for (unsigned I = 0, N = Captures.size(); I != N; ++I) {
- if (Captures[I].isExplicit())
- ++Data.NumExplicitCaptures;
-
- *ToCapture++ = Captures[I];
- }
+ assert(NumCaptures == Class->capture_size() && "Wrong number of captures");
+ assert(CaptureDefault == Class->getLambdaCaptureDefault());
// Copy initialization expressions for the non-static data members.
Stmt **Stored = getStoredStmts();
@@ -1128,22 +1111,24 @@ LambdaExpr::LambdaExpr(QualType T, SourceRange IntroducerRange,
setDependence(computeDependence(this, ContainsUnexpandedParameterPack));
}
-LambdaExpr *LambdaExpr::Create(
- const ASTContext &Context, CXXRecordDecl *Class,
- SourceRange IntroducerRange, LambdaCaptureDefault CaptureDefault,
- SourceLocation CaptureDefaultLoc, ArrayRef<LambdaCapture> Captures,
- bool ExplicitParams, bool ExplicitResultType, ArrayRef<Expr *> CaptureInits,
- SourceLocation ClosingBrace, bool ContainsUnexpandedParameterPack) {
+LambdaExpr *LambdaExpr::Create(const ASTContext &Context, CXXRecordDecl *Class,
+ SourceRange IntroducerRange,
+ LambdaCaptureDefault CaptureDefault,
+ SourceLocation CaptureDefaultLoc,
+ bool ExplicitParams, bool ExplicitResultType,
+ ArrayRef<Expr *> CaptureInits,
+ SourceLocation ClosingBrace,
+ bool ContainsUnexpandedParameterPack) {
// Determine the type of the expression (i.e., the type of the
// function object we're creating).
QualType T = Context.getTypeDeclType(Class);
- unsigned Size = totalSizeToAlloc<Stmt *>(Captures.size() + 1);
+ unsigned Size = totalSizeToAlloc<Stmt *>(CaptureInits.size() + 1);
void *Mem = Context.Allocate(Size);
return new (Mem)
LambdaExpr(T, IntroducerRange, CaptureDefault, CaptureDefaultLoc,
- Captures, ExplicitParams, ExplicitResultType, CaptureInits,
- ClosingBrace, ContainsUnexpandedParameterPack);
+ ExplicitParams, ExplicitResultType, CaptureInits, ClosingBrace,
+ ContainsUnexpandedParameterPack);
}
LambdaExpr *LambdaExpr::CreateDeserialized(const ASTContext &C,
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index b4336aa..e751a73 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1782,6 +1782,8 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
CaptureInits.push_back(Init.get());
}
+ Class->setCaptures(Captures);
+
// C++11 [expr.prim.lambda]p6:
// The closure type for a lambda-expression with no lambda-capture
// has a public non-virtual non-explicit const conversion function
@@ -1811,7 +1813,6 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
LambdaExpr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange,
CaptureDefault, CaptureDefaultLoc,
- Captures,
ExplicitParams, ExplicitResultType,
CaptureInits, EndLoc,
ContainsUnexpandedParameterPack);