summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp115
1 files changed, 51 insertions, 64 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp
index 8220641..884add2 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp
@@ -226,15 +226,16 @@ getGenericLambdaTemplateParameterList(LambdaScopeInfo *LSI, Sema &SemaRef) {
if (LSI->GLTemplateParameterList)
return LSI->GLTemplateParameterList;
- if (LSI->AutoTemplateParams.size()) {
+ if (!LSI->AutoTemplateParams.empty()) {
SourceRange IntroRange = LSI->IntroducerRange;
SourceLocation LAngleLoc = IntroRange.getBegin();
SourceLocation RAngleLoc = IntroRange.getEnd();
LSI->GLTemplateParameterList = TemplateParameterList::Create(
SemaRef.Context,
/*Template kw loc*/ SourceLocation(), LAngleLoc,
- (NamedDecl **)LSI->AutoTemplateParams.data(),
- LSI->AutoTemplateParams.size(), RAngleLoc);
+ llvm::makeArrayRef((NamedDecl *const *)LSI->AutoTemplateParams.data(),
+ LSI->AutoTemplateParams.size()),
+ RAngleLoc);
}
return LSI->GLTemplateParameterList;
}
@@ -685,7 +686,8 @@ void Sema::deduceClosureReturnType(CapturingScopeInfo &CSI) {
QualType ReturnType =
(RetE ? RetE->getType() : Context.VoidTy).getUnqualifiedType();
- if (Context.hasSameType(ReturnType, CSI.ReturnType))
+ if (Context.getCanonicalFunctionResultType(ReturnType) ==
+ Context.getCanonicalFunctionResultType(CSI.ReturnType))
continue;
// FIXME: This is a poor diagnostic for ReturnStmts without expressions.
@@ -698,18 +700,11 @@ void Sema::deduceClosureReturnType(CapturingScopeInfo &CSI) {
}
}
-QualType Sema::performLambdaInitCaptureInitialization(SourceLocation Loc,
- bool ByRef,
- IdentifierInfo *Id,
- Expr *&Init) {
-
- // We do not need to distinguish between direct-list-initialization
- // and copy-list-initialization here, because we will always deduce
- // std::initializer_list<T>, and direct- and copy-list-initialization
- // always behave the same for such a type.
- // FIXME: We should model whether an '=' was present.
- const bool IsDirectInit = isa<ParenListExpr>(Init) || isa<InitListExpr>(Init);
-
+QualType Sema::buildLambdaInitCaptureInitialization(SourceLocation Loc,
+ bool ByRef,
+ IdentifierInfo *Id,
+ bool IsDirectInit,
+ Expr *&Init) {
// Create an 'auto' or 'auto&' TypeSourceInfo that we can use to
// deduce against.
QualType DeductType = Context.getAutoDeductType();
@@ -722,50 +717,16 @@ QualType Sema::performLambdaInitCaptureInitialization(SourceLocation Loc,
}
TypeSourceInfo *TSI = TLB.getTypeSourceInfo(Context, DeductType);
- // Are we a non-list direct initialization?
- ParenListExpr *CXXDirectInit = dyn_cast<ParenListExpr>(Init);
-
- Expr *DeduceInit = Init;
- // Initializer could be a C++ direct-initializer. Deduction only works if it
- // contains exactly one expression.
- if (CXXDirectInit) {
- if (CXXDirectInit->getNumExprs() == 0) {
- Diag(CXXDirectInit->getLocStart(), diag::err_init_capture_no_expression)
- << DeclarationName(Id) << TSI->getType() << Loc;
- return QualType();
- } else if (CXXDirectInit->getNumExprs() > 1) {
- Diag(CXXDirectInit->getExpr(1)->getLocStart(),
- diag::err_init_capture_multiple_expressions)
- << DeclarationName(Id) << TSI->getType() << Loc;
- return QualType();
- } else {
- DeduceInit = CXXDirectInit->getExpr(0);
- if (isa<InitListExpr>(DeduceInit))
- Diag(CXXDirectInit->getLocStart(), diag::err_init_capture_paren_braces)
- << DeclarationName(Id) << Loc;
- }
- }
-
- // Now deduce against the initialization expression and store the deduced
- // type below.
- QualType DeducedType;
- if (DeduceAutoType(TSI, DeduceInit, DeducedType) == DAR_Failed) {
- if (isa<InitListExpr>(Init))
- Diag(Loc, diag::err_init_capture_deduction_failure_from_init_list)
- << DeclarationName(Id)
- << (DeduceInit->getType().isNull() ? TSI->getType()
- : DeduceInit->getType())
- << DeduceInit->getSourceRange();
- else
- Diag(Loc, diag::err_init_capture_deduction_failure)
- << DeclarationName(Id) << TSI->getType()
- << (DeduceInit->getType().isNull() ? TSI->getType()
- : DeduceInit->getType())
- << DeduceInit->getSourceRange();
- }
+ // Deduce the type of the init capture.
+ QualType DeducedType = deduceVarTypeFromInitializer(
+ /*VarDecl*/nullptr, DeclarationName(Id), DeductType, TSI,
+ SourceRange(Loc, Loc), IsDirectInit, Init);
if (DeducedType.isNull())
return QualType();
+ // Are we a non-list direct initialization?
+ ParenListExpr *CXXDirectInit = dyn_cast<ParenListExpr>(Init);
+
// Perform initialization analysis and ensure any implicit conversions
// (such as lvalue-to-rvalue) are enforced.
InitializedEntity Entity =
@@ -802,9 +763,10 @@ QualType Sema::performLambdaInitCaptureInitialization(SourceLocation Loc,
return DeducedType;
}
-VarDecl *Sema::createLambdaInitCaptureVarDecl(SourceLocation Loc,
- QualType InitCaptureType, IdentifierInfo *Id, Expr *Init) {
-
+VarDecl *Sema::createLambdaInitCaptureVarDecl(SourceLocation Loc,
+ QualType InitCaptureType,
+ IdentifierInfo *Id,
+ unsigned InitStyle, Expr *Init) {
TypeSourceInfo *TSI = Context.getTrivialTypeSourceInfo(InitCaptureType,
Loc);
// Create a dummy variable representing the init-capture. This is not actually
@@ -815,6 +777,8 @@ VarDecl *Sema::createLambdaInitCaptureVarDecl(SourceLocation Loc,
Loc, Id, InitCaptureType, TSI, SC_Auto);
NewVD->setInitCapture(true);
NewVD->setReferenced(true);
+ // FIXME: Pass in a VarDecl::InitializationStyle.
+ NewVD->setInitStyle(static_cast<VarDecl::InitializationStyle>(InitStyle));
NewVD->markUsed(Context);
NewVD->setInit(Init);
return NewVD;
@@ -1013,8 +977,23 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
// in this case.
if (C->InitCaptureType.get().isNull())
continue;
- Var = createLambdaInitCaptureVarDecl(C->Loc, C->InitCaptureType.get(),
- C->Id, C->Init.get());
+
+ unsigned InitStyle;
+ switch (C->InitKind) {
+ case LambdaCaptureInitKind::NoInit:
+ llvm_unreachable("not an init-capture?");
+ case LambdaCaptureInitKind::CopyInit:
+ InitStyle = VarDecl::CInit;
+ break;
+ case LambdaCaptureInitKind::DirectInit:
+ InitStyle = VarDecl::CallInit;
+ break;
+ case LambdaCaptureInitKind::ListInit:
+ InitStyle = VarDecl::ListInit;
+ break;
+ }
+ Var = createLambdaInitCaptureVarDecl(C->Loc, C->InitCaptureType.get(),
+ C->Id, InitStyle, C->Init.get());
// C++1y [expr.prim.lambda]p11:
// An init-capture behaves as if it declares and explicitly
// captures a variable [...] whose declarative region is the
@@ -1022,6 +1001,9 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
if (Var)
PushOnScopeChains(Var, CurScope, false);
} else {
+ assert(C->InitKind == LambdaCaptureInitKind::NoInit &&
+ "init capture has valid but null init?");
+
// C++11 [expr.prim.lambda]p8:
// If a lambda-capture includes a capture-default that is &, the
// identifiers in the lambda-capture shall not be preceded by &.
@@ -1160,6 +1142,12 @@ static void addFunctionPointerConversion(Sema &S,
SourceRange IntroducerRange,
CXXRecordDecl *Class,
CXXMethodDecl *CallOperator) {
+ // This conversion is explicitly disabled if the lambda's function has
+ // pass_object_size attributes on any of its parameters.
+ if (std::any_of(CallOperator->param_begin(), CallOperator->param_end(),
+ std::mem_fn(&ParmVarDecl::hasAttr<PassObjectSizeAttr>)))
+ return;
+
// Add the conversion to function pointer.
const FunctionProtoType *CallOpProto =
CallOperator->getType()->getAs<FunctionProtoType>();
@@ -1700,8 +1688,7 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation,
SC_None);
BlockDecl::Capture Capture(/*Variable=*/CapVar, /*ByRef=*/false,
/*Nested=*/false, /*Copy=*/Init.get());
- Block->setCaptures(Context, &Capture, &Capture + 1,
- /*CapturesCXXThis=*/false);
+ Block->setCaptures(Context, Capture, /*CapturesCXXThis=*/false);
// Add a fake function body to the block. IR generation is responsible
// for filling in the actual body, which cannot be expressed as an AST.
OpenPOWER on IntegriCloud