Updated to Clang 3.5a.
Change-Id: I8127eb568f674c2e72635b639a3295381fe8af82
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index a7d5b65..0d287f7 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
#include "clang/Sema/DeclSpec.h"
+#include "TypeLocBuilder.h"
#include "clang/AST/ASTLambda.h"
#include "clang/AST/ExprCXX.h"
#include "clang/Basic/TargetInfo.h"
@@ -21,115 +22,204 @@
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaLambda.h"
-#include "TypeLocBuilder.h"
using namespace clang;
using namespace sema;
-// returns -1 if none of the lambdas on the scope stack can capture.
-// A lambda 'L' is capture-ready for a certain variable 'V' if,
-// - its enclosing context is non-dependent
-// - and if the chain of lambdas between L and the lambda in which
-// V is potentially used, call all capture or have captured V.
-static inline int GetScopeIndexOfNearestCaptureReadyLambda(
- ArrayRef<clang::sema::FunctionScopeInfo*> FunctionScopes,
- DeclContext *const CurContext, VarDecl *VD) {
+/// \brief Examines the FunctionScopeInfo stack to determine the nearest
+/// enclosing lambda (to the current lambda) that is 'capture-ready' for
+/// the variable referenced in the current lambda (i.e. \p VarToCapture).
+/// If successful, returns the index into Sema's FunctionScopeInfo stack
+/// of the capture-ready lambda's LambdaScopeInfo.
+///
+/// Climbs down the stack of lambdas (deepest nested lambda - i.e. current
+/// lambda - is on top) to determine the index of the nearest enclosing/outer
+/// lambda that is ready to capture the \p VarToCapture being referenced in
+/// the current lambda.
+/// As we climb down the stack, we want the index of the first such lambda -
+/// that is the lambda with the highest index that is 'capture-ready'.
+///
+/// A lambda 'L' is capture-ready for 'V' (var or this) if:
+/// - its enclosing context is non-dependent
+/// - and if the chain of lambdas between L and the lambda in which
+/// V is potentially used (i.e. the lambda at the top of the scope info
+/// stack), can all capture or have already captured V.
+/// If \p VarToCapture is 'null' then we are trying to capture 'this'.
+///
+/// Note that a lambda that is deemed 'capture-ready' still needs to be checked
+/// for whether it is 'capture-capable' (see
+/// getStackIndexOfNearestEnclosingCaptureCapableLambda), before it can truly
+/// capture.
+///
+/// \param FunctionScopes - Sema's stack of nested FunctionScopeInfo's (which a
+/// LambdaScopeInfo inherits from). The current/deepest/innermost lambda
+/// is at the top of the stack and has the highest index.
+/// \param VarToCapture - the variable to capture. If NULL, capture 'this'.
+///
+/// \returns An Optional<unsigned> Index that if evaluates to 'true' contains
+/// the index (into Sema's FunctionScopeInfo stack) of the innermost lambda
+/// which is capture-ready. If the return value evaluates to 'false' then
+/// no lambda is capture-ready for \p VarToCapture.
+
+static inline Optional<unsigned>
+getStackIndexOfNearestEnclosingCaptureReadyLambda(
+ ArrayRef<const clang::sema::FunctionScopeInfo *> FunctionScopes,
+ VarDecl *VarToCapture) {
+ // Label failure to capture.
+ const Optional<unsigned> NoLambdaIsCaptureReady;
+
+ assert(
+ isa<clang::sema::LambdaScopeInfo>(
+ FunctionScopes[FunctionScopes.size() - 1]) &&
+ "The function on the top of sema's function-info stack must be a lambda");
- DeclContext *EnclosingDC = CurContext;
- // If VD is null, we are attempting to capture 'this'
- const bool IsCapturingThis = !VD;
+ // If VarToCapture is null, we are attempting to capture 'this'.
+ const bool IsCapturingThis = !VarToCapture;
const bool IsCapturingVariable = !IsCapturingThis;
- int RetIndex = -1;
+
+ // Start with the current lambda at the top of the stack (highest index).
unsigned CurScopeIndex = FunctionScopes.size() - 1;
- while (!EnclosingDC->isTranslationUnit() &&
- EnclosingDC->isDependentContext() && isLambdaCallOperator(EnclosingDC)) {
- RetIndex = CurScopeIndex;
- clang::sema::LambdaScopeInfo *LSI =
- cast<sema::LambdaScopeInfo>(FunctionScopes[CurScopeIndex]);
- // We have crawled up to an intervening lambda that contains the
- // variable declaration - so not only does it not need to capture;
- // none of the enclosing lambdas need to capture it, and since all
- // other nested lambdas are dependent (otherwise we wouldn't have
- // arrived here) - we don't yet have a lambda that can capture the
+ DeclContext *EnclosingDC =
+ cast<sema::LambdaScopeInfo>(FunctionScopes[CurScopeIndex])->CallOperator;
+
+ do {
+ const clang::sema::LambdaScopeInfo *LSI =
+ cast<sema::LambdaScopeInfo>(FunctionScopes[CurScopeIndex]);
+ // IF we have climbed down to an intervening enclosing lambda that contains
+ // the variable declaration - it obviously can/must not capture the
// variable.
- if (IsCapturingVariable && VD->getDeclContext()->Equals(EnclosingDC))
- return -1;
- // All intervening lambda call operators have to be able to capture.
+ // Since its enclosing DC is dependent, all the lambdas between it and the
+ // innermost nested lambda are dependent (otherwise we wouldn't have
+ // arrived here) - so we don't yet have a lambda that can capture the
+ // variable.
+ if (IsCapturingVariable &&
+ VarToCapture->getDeclContext()->Equals(EnclosingDC))
+ return NoLambdaIsCaptureReady;
+
+ // For an enclosing lambda to be capture ready for an entity, all
+ // intervening lambda's have to be able to capture that entity. If even
+ // one of the intervening lambda's is not capable of capturing the entity
+ // then no enclosing lambda can ever capture that entity.
+ // For e.g.
+ // const int x = 10;
+ // [=](auto a) { #1
+ // [](auto b) { #2 <-- an intervening lambda that can never capture 'x'
+ // [=](auto c) { #3
+ // f(x, c); <-- can not lead to x's speculative capture by #1 or #2
+ // }; }; };
// If they do not have a default implicit capture, check to see
// if the entity has already been explicitly captured.
- // If even a single dependent enclosing lambda lacks the capability
- // to ever capture this variable, there is no further enclosing
+ // If even a single dependent enclosing lambda lacks the capability
+ // to ever capture this variable, there is no further enclosing
// non-dependent lambda that can capture this variable.
if (LSI->ImpCaptureStyle == sema::LambdaScopeInfo::ImpCap_None) {
- if (IsCapturingVariable && !LSI->isCaptured(VD))
- return -1;
+ if (IsCapturingVariable && !LSI->isCaptured(VarToCapture))
+ return NoLambdaIsCaptureReady;
if (IsCapturingThis && !LSI->isCXXThisCaptured())
- return -1;
+ return NoLambdaIsCaptureReady;
}
EnclosingDC = getLambdaAwareParentOfDeclContext(EnclosingDC);
+
+ assert(CurScopeIndex);
--CurScopeIndex;
- }
- // If the enclosingDC is not dependent, then the immediately nested lambda
- // is capture-ready.
- if (!EnclosingDC->isDependentContext())
- return RetIndex;
- return -1;
-}
-// Given a lambda's call operator and a variable (or null for 'this'),
-// compute the nearest enclosing lambda that is capture-ready (i.e
-// the enclosing context is not dependent, and all intervening lambdas can
-// either implicitly or explicitly capture Var)
-//
-// The approach is as follows, for the entity VD ('this' if null):
-// - start with the current lambda
-// - if it is non-dependent and can capture VD, return it.
-// - if it is dependent and has an implicit or explicit capture, check its parent
-// whether the parent is non-depdendent and all its intervening lambdas
-// can capture, if so return the child.
-// [Note: When we hit a generic lambda specialization, do not climb up
-// the scope stack any further since not only do we not need to,
-// the scope stack will often not be synchronized with any lambdas
-// enclosing the specialized generic lambda]
-//
-// Return the CallOperator of the capturable lambda and set function scope
-// index to the correct index within the function scope stack to correspond
-// to the capturable lambda.
-// If VarDecl *VD is null, we check for 'this' capture.
-CXXMethodDecl* clang::GetInnermostEnclosingCapturableLambda(
- ArrayRef<sema::FunctionScopeInfo*> FunctionScopes,
- unsigned &FunctionScopeIndex,
- DeclContext *const CurContext, VarDecl *VD,
- Sema &S) {
+ } while (!EnclosingDC->isTranslationUnit() &&
+ EnclosingDC->isDependentContext() &&
+ isLambdaCallOperator(EnclosingDC));
- const int IndexOfCaptureReadyLambda =
- GetScopeIndexOfNearestCaptureReadyLambda(FunctionScopes,CurContext, VD);
- if (IndexOfCaptureReadyLambda == -1) return 0;
- assert(IndexOfCaptureReadyLambda >= 0);
- const unsigned IndexOfCaptureReadyLambdaU =
- static_cast<unsigned>(IndexOfCaptureReadyLambda);
- sema::LambdaScopeInfo *const CaptureReadyLambdaLSI =
- cast<sema::LambdaScopeInfo>(FunctionScopes[IndexOfCaptureReadyLambdaU]);
- // If VD is null, we are attempting to capture 'this'
- const bool IsCapturingThis = !VD;
+ assert(CurScopeIndex < (FunctionScopes.size() - 1));
+ // If the enclosingDC is not dependent, then the immediately nested lambda
+ // (one index above) is capture-ready.
+ if (!EnclosingDC->isDependentContext())
+ return CurScopeIndex + 1;
+ return NoLambdaIsCaptureReady;
+}
+
+/// \brief Examines the FunctionScopeInfo stack to determine the nearest
+/// enclosing lambda (to the current lambda) that is 'capture-capable' for
+/// the variable referenced in the current lambda (i.e. \p VarToCapture).
+/// If successful, returns the index into Sema's FunctionScopeInfo stack
+/// of the capture-capable lambda's LambdaScopeInfo.
+///
+/// Given the current stack of lambdas being processed by Sema and
+/// the variable of interest, to identify the nearest enclosing lambda (to the
+/// current lambda at the top of the stack) that can truly capture
+/// a variable, it has to have the following two properties:
+/// a) 'capture-ready' - be the innermost lambda that is 'capture-ready':
+/// - climb down the stack (i.e. starting from the innermost and examining
+/// each outer lambda step by step) checking if each enclosing
+/// lambda can either implicitly or explicitly capture the variable.
+/// Record the first such lambda that is enclosed in a non-dependent
+/// context. If no such lambda currently exists return failure.
+/// b) 'capture-capable' - make sure the 'capture-ready' lambda can truly
+/// capture the variable by checking all its enclosing lambdas:
+/// - check if all outer lambdas enclosing the 'capture-ready' lambda
+/// identified above in 'a' can also capture the variable (this is done
+/// via tryCaptureVariable for variables and CheckCXXThisCapture for
+/// 'this' by passing in the index of the Lambda identified in step 'a')
+///
+/// \param FunctionScopes - Sema's stack of nested FunctionScopeInfo's (which a
+/// LambdaScopeInfo inherits from). The current/deepest/innermost lambda
+/// is at the top of the stack.
+///
+/// \param VarToCapture - the variable to capture. If NULL, capture 'this'.
+///
+///
+/// \returns An Optional<unsigned> Index that if evaluates to 'true' contains
+/// the index (into Sema's FunctionScopeInfo stack) of the innermost lambda
+/// which is capture-capable. If the return value evaluates to 'false' then
+/// no lambda is capture-capable for \p VarToCapture.
+
+Optional<unsigned> clang::getStackIndexOfNearestEnclosingCaptureCapableLambda(
+ ArrayRef<const sema::FunctionScopeInfo *> FunctionScopes,
+ VarDecl *VarToCapture, Sema &S) {
+
+ const Optional<unsigned> NoLambdaIsCaptureCapable;
+
+ const Optional<unsigned> OptionalStackIndex =
+ getStackIndexOfNearestEnclosingCaptureReadyLambda(FunctionScopes,
+ VarToCapture);
+ if (!OptionalStackIndex)
+ return NoLambdaIsCaptureCapable;
+
+ const unsigned IndexOfCaptureReadyLambda = OptionalStackIndex.getValue();
+ assert(((IndexOfCaptureReadyLambda != (FunctionScopes.size() - 1)) ||
+ S.getCurGenericLambda()) &&
+ "The capture ready lambda for a potential capture can only be the "
+ "current lambda if it is a generic lambda");
+
+ const sema::LambdaScopeInfo *const CaptureReadyLambdaLSI =
+ cast<sema::LambdaScopeInfo>(FunctionScopes[IndexOfCaptureReadyLambda]);
+
+ // If VarToCapture is null, we are attempting to capture 'this'
+ const bool IsCapturingThis = !VarToCapture;
const bool IsCapturingVariable = !IsCapturingThis;
if (IsCapturingVariable) {
- // Now check to see if this lambda can truly capture, and also
- // if all enclosing lambdas of this lambda allow this capture.
+ // Check if the capture-ready lambda can truly capture the variable, by
+ // checking whether all enclosing lambdas of the capture-ready lambda allow
+ // the capture - i.e. make sure it is capture-capable.
QualType CaptureType, DeclRefType;
- const bool CanCaptureVariable = !S.tryCaptureVariable(VD,
- /*ExprVarIsUsedInLoc*/SourceLocation(), clang::Sema::TryCapture_Implicit,
- /*EllipsisLoc*/ SourceLocation(),
- /*BuildAndDiagnose*/false, CaptureType, DeclRefType,
- &IndexOfCaptureReadyLambdaU);
- if (!CanCaptureVariable) return 0;
- } else {
- const bool CanCaptureThis = !S.CheckCXXThisCapture(
- CaptureReadyLambdaLSI->PotentialThisCaptureLocation, false, false,
- &IndexOfCaptureReadyLambdaU);
- if (!CanCaptureThis) return 0;
- } // end 'this' capture test
- FunctionScopeIndex = IndexOfCaptureReadyLambdaU;
- return CaptureReadyLambdaLSI->CallOperator;
+ const bool CanCaptureVariable =
+ !S.tryCaptureVariable(VarToCapture,
+ /*ExprVarIsUsedInLoc*/ SourceLocation(),
+ clang::Sema::TryCapture_Implicit,
+ /*EllipsisLoc*/ SourceLocation(),
+ /*BuildAndDiagnose*/ false, CaptureType,
+ DeclRefType, &IndexOfCaptureReadyLambda);
+ if (!CanCaptureVariable)
+ return NoLambdaIsCaptureCapable;
+ } else {
+ // Check if the capture-ready lambda can truly capture 'this' by checking
+ // whether all enclosing lambdas of the capture-ready lambda can capture
+ // 'this'.
+ const bool CanCaptureThis =
+ !S.CheckCXXThisCapture(
+ CaptureReadyLambdaLSI->PotentialThisCaptureLocation,
+ /*Explicit*/ false, /*BuildAndDiagnose*/ false,
+ &IndexOfCaptureReadyLambda);
+ if (!CanCaptureThis)
+ return NoLambdaIsCaptureCapable;
+ }
+ return IndexOfCaptureReadyLambda;
}
static inline TemplateParameterList *
@@ -142,17 +232,14 @@
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);
+ SemaRef.Context,
+ /*Template kw loc*/ SourceLocation(), LAngleLoc,
+ (NamedDecl **)LSI->AutoTemplateParams.data(),
+ LSI->AutoTemplateParams.size(), RAngleLoc);
}
return LSI->GLTemplateParameterList;
}
-
-
CXXRecordDecl *Sema::createLambdaClosureType(SourceRange IntroducerRange,
TypeSourceInfo *Info,
bool KnownDependent,
@@ -169,7 +256,7 @@
IsGenericLambda,
CaptureDefault);
DC->addDecl(Class);
-
+
return Class;
}
@@ -277,10 +364,10 @@
// dependent type.
if (Class->isDependentContext() || TemplateParams) {
const FunctionProtoType *FPT = MethodType->castAs<FunctionProtoType>();
- QualType Result = FPT->getResultType();
+ QualType Result = FPT->getReturnType();
if (Result->isUndeducedType()) {
Result = SubstAutoType(Result, Context.DependentTy);
- MethodType = Context.getFunctionType(Result, FPT->getArgTypes(),
+ MethodType = Context.getFunctionType(Result, FPT->getParamTypes(),
FPT->getExtProtoInfo());
}
}
@@ -331,10 +418,8 @@
const_cast<ParmVarDecl **>(Params.end()),
/*CheckParameterNames=*/false);
- for (CXXMethodDecl::param_iterator P = Method->param_begin(),
- PEnd = Method->param_end();
- P != PEnd; ++P)
- (*P)->setOwningFunction(Method);
+ for (auto P : Method->params())
+ P->setOwningFunction(Method);
}
Decl *ManglingContextDecl;
@@ -369,8 +454,8 @@
LSI->Mutable = Mutable;
if (ExplicitResultType) {
- LSI->ReturnType = CallOperator->getResultType();
-
+ LSI->ReturnType = CallOperator->getReturnType();
+
if (!LSI->ReturnType->isDependentType() &&
!LSI->ReturnType->isVoidType()) {
if (RequireCompleteType(CallOperator->getLocStart(), LSI->ReturnType,
@@ -651,6 +736,9 @@
return QualType();
} else {
DeduceInit = CXXDirectInit->getExpr(0);
+ if (isa<InitListExpr>(DeduceInit))
+ Diag(CXXDirectInit->getLocStart(), diag::err_init_capture_paren_braces)
+ << DeclarationName(Id) << Loc;
}
}
@@ -811,14 +899,13 @@
ExplicitResultType = FTI.hasTrailingReturnType();
- if (FTI.NumArgs == 1 && !FTI.isVariadic && FTI.ArgInfo[0].Ident == 0 &&
- cast<ParmVarDecl>(FTI.ArgInfo[0].Param)->getType()->isVoidType()) {
+ if (FTI.NumParams == 1 && !FTI.isVariadic && FTI.Params[0].Ident == 0 &&
+ cast<ParmVarDecl>(FTI.Params[0].Param)->getType()->isVoidType()) {
// Empty arg list, don't push any params.
- checkVoidParamDecl(cast<ParmVarDecl>(FTI.ArgInfo[0].Param));
} else {
- Params.reserve(FTI.NumArgs);
- for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i)
- Params.push_back(cast<ParmVarDecl>(FTI.ArgInfo[i].Param));
+ Params.reserve(FTI.NumParams);
+ for (unsigned i = 0, e = FTI.NumParams; i != e; ++i)
+ Params.push_back(cast<ParmVarDecl>(FTI.Params[i].Param));
}
// Check for unexpanded parameter packs in the method type.
@@ -848,6 +935,23 @@
ExplicitResultType,
!Method->isConst());
+ // C++11 [expr.prim.lambda]p9:
+ // A lambda-expression whose smallest enclosing scope is a block scope is a
+ // local lambda expression; any other lambda expression shall not have a
+ // capture-default or simple-capture in its lambda-introducer.
+ //
+ // For simple-captures, this is covered by the check below that any named
+ // entity is a variable that can be captured.
+ //
+ // For DR1632, we also allow a capture-default in any context where we can
+ // odr-use 'this' (in particular, in a default initializer for a non-static
+ // data member).
+ if (Intro.Default != LCD_None && !Class->getParent()->isFunctionOrMethod() &&
+ (getCurrentThisType().isNull() ||
+ CheckCXXThisCapture(SourceLocation(), /*Explicit*/true,
+ /*BuildAndDiagnose*/false)))
+ Diag(Intro.DefaultLoc, diag::err_capture_default_non_local);
+
// Distinct capture names, for diagnostics.
llvm::SmallSet<IdentifierInfo*, 8> CaptureNames;
@@ -958,6 +1062,8 @@
}
Var = R.getAsSingle<VarDecl>();
+ if (Var && DiagnoseUseOfDecl(Var, C->Loc))
+ continue;
}
// C++11 [expr.prim.lambda]p8:
@@ -1045,12 +1151,9 @@
LambdaScopeInfo *LSI = getCurLambda();
CXXRecordDecl *Class = LSI->Lambda;
Class->setInvalidDecl();
- SmallVector<Decl*, 4> Fields;
- for (RecordDecl::field_iterator i = Class->field_begin(),
- e = Class->field_end(); i != e; ++i)
- Fields.push_back(*i);
- ActOnFields(0, Class->getLocation(), Class, Fields,
- SourceLocation(), SourceLocation(), 0);
+ SmallVector<Decl*, 4> Fields(Class->fields());
+ ActOnFields(0, Class->getLocation(), Class, Fields, SourceLocation(),
+ SourceLocation(), 0);
CheckCompletedCXXClass(Class);
PopFunctionScopeInfo();
@@ -1077,8 +1180,9 @@
InvokerExtInfo.TypeQuals = 0;
assert(InvokerExtInfo.RefQualifier == RQ_None &&
"Lambda's call operator should not have a reference qualifier");
- InvokerFunctionTy = S.Context.getFunctionType(CallOpProto->getResultType(),
- CallOpProto->getArgTypes(), InvokerExtInfo);
+ InvokerFunctionTy =
+ S.Context.getFunctionType(CallOpProto->getReturnType(),
+ CallOpProto->getParamTypes(), InvokerExtInfo);
PtrToFunctionTy = S.Context.getPointerType(InvokerFunctionTy);
}
@@ -1122,7 +1226,7 @@
ConvTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>();
// Get the result of the conversion function which is a pointer-to-function.
PointerTypeLoc PtrToFunctionTL =
- ConvTL.getResultLoc().getAs<PointerTypeLoc>();
+ ConvTL.getReturnLoc().getAs<PointerTypeLoc>();
// Do the same for the TypeSourceInfo that is used to name the conversion
// operator.
PointerTypeLoc ConvNamePtrToFunctionTL =
@@ -1157,8 +1261,8 @@
From->getTypeSourceInfo(),
From->getStorageClass(),
/*DefaultArg=*/0));
- CallOpConvTL.setArg(I, From);
- CallOpConvNameTL.setArg(I, From);
+ CallOpConvTL.setParam(I, From);
+ CallOpConvNameTL.setParam(I, From);
}
CXXConversionDecl *Conversion
@@ -1244,7 +1348,7 @@
FunctionProtoType::ExtProtoInfo ExtInfo = Proto->getExtProtoInfo();
ExtInfo.TypeQuals = 0;
QualType FunctionTy = S.Context.getFunctionType(
- Proto->getResultType(), Proto->getArgTypes(), ExtInfo);
+ Proto->getReturnType(), Proto->getParamTypes(), ExtInfo);
BlockPtrTy = S.Context.getBlockPointerType(FunctionTy);
}
@@ -1369,7 +1473,7 @@
const FunctionProtoType *Proto
= CallOperator->getType()->getAs<FunctionProtoType>();
QualType FunctionTy = Context.getFunctionType(
- LSI->ReturnType, Proto->getArgTypes(), Proto->getExtProtoInfo());
+ LSI->ReturnType, Proto->getParamTypes(), Proto->getExtProtoInfo());
CallOperator->setType(FunctionTy);
}
// C++ [expr.prim.lambda]p7:
@@ -1407,12 +1511,9 @@
addBlockPointerConversion(*this, IntroducerRange, Class, CallOperator);
// Finalize the lambda class.
- SmallVector<Decl*, 4> Fields;
- for (RecordDecl::field_iterator i = Class->field_begin(),
- e = Class->field_end(); i != e; ++i)
- Fields.push_back(*i);
- ActOnFields(0, Class->getLocation(), Class, Fields,
- SourceLocation(), SourceLocation(), 0);
+ SmallVector<Decl*, 4> Fields(Class->fields());
+ ActOnFields(0, Class->getLocation(), Class, Fields, SourceLocation(),
+ SourceLocation(), 0);
CheckCompletedCXXClass(Class);
}