aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaLambda.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-02-14 22:28:59 +0000
committerDouglas Gregor <dgregor@apple.com>2012-02-14 22:28:59 +0000
commitc6889e7ed16604c51994e1f11becf213fdc64eb3 (patch)
treecd67da6857b1e624c3c190e4a9e3648c606381fb /lib/Sema/SemaLambda.cpp
parent57b9c4e9d85971e20ab0dac3eadabae672c43c62 (diff)
Implement C++ core issue 974, which permits default arguments for
lambda expressions. Because these issue was pulled back from Ready status at the Kona meeting, we still emit an ExtWarn when using default arguments for lambda expressions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150519 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaLambda.cpp')
-rw-r--r--lib/Sema/SemaLambda.cpp49
1 files changed, 28 insertions, 21 deletions
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index 8b8a083a06..34ccb2d3dd 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -36,7 +36,8 @@ CXXRecordDecl *Sema::createLambdaClosureType(SourceRange IntroducerRange) {
CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class,
SourceRange IntroducerRange,
TypeSourceInfo *MethodType,
- SourceLocation EndLoc) {
+ SourceLocation EndLoc,
+ llvm::ArrayRef<ParmVarDecl *> Params) {
// C++11 [expr.prim.lambda]p5:
// The closure type for a lambda-expression has a public inline function
// call operator (13.5.4) whose parameters and return type are described by
@@ -66,6 +67,19 @@ CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class,
// context, so that the Scope stack matches the lexical nesting.
Method->setLexicalDeclContext(Class->getDeclContext());
+ // Add parameters.
+ if (!Params.empty()) {
+ Method->setParams(Params);
+ CheckParmsForFunctionDef(const_cast<ParmVarDecl **>(Params.begin()),
+ 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);
+ }
+
return Method;
}
@@ -109,18 +123,11 @@ void Sema::finishLambdaExplicitCaptures(LambdaScopeInfo *LSI) {
LSI->finishedExplicitCaptures();
}
-void Sema::addLambdaParameters(CXXMethodDecl *CallOperator, Scope *CurScope,
- llvm::ArrayRef<ParmVarDecl *> Params) {
- CallOperator->setParams(Params);
- CheckParmsForFunctionDef(const_cast<ParmVarDecl **>(Params.begin()),
- const_cast<ParmVarDecl **>(Params.end()),
- /*CheckParameterNames=*/false);
-
+void Sema::addLambdaParameters(CXXMethodDecl *CallOperator, Scope *CurScope) {
// Introduce our parameters into the function scope
for (unsigned p = 0, NumParams = CallOperator->getNumParams();
p < NumParams; ++p) {
ParmVarDecl *Param = CallOperator->getParamDecl(p);
- Param->setOwningFunction(CallOperator);
// If this has an identifier, add it to the scope stack.
if (CurScope && Param->getIdentifier()) {
@@ -141,6 +148,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
bool ExplicitParams = true;
bool ExplicitResultType = true;
SourceLocation EndLoc;
+ llvm::ArrayRef<ParmVarDecl *> Params;
if (ParamInfo.getNumTypeObjects() == 0) {
// C++11 [expr.prim.lambda]p4:
// If a lambda-expression does not include a lambda-declarator, it is as
@@ -166,11 +174,6 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
if (!FTI.hasMutableQualifier())
FTI.TypeQuals |= DeclSpec::TQ_const;
- // C++11 [expr.prim.lambda]p5:
- // [...] Default arguments (8.3.6) shall not be specified in the
- // parameter-declaration-clause of a lambda-declarator.
- CheckExtraCXXDefaultArguments(ParamInfo);
-
MethodTyInfo = GetTypeForDeclarator(ParamInfo, CurScope);
assert(MethodTyInfo && "no type from lambda-declarator");
EndLoc = ParamInfo.getSourceRange().getEnd();
@@ -178,10 +181,18 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
ExplicitResultType
= MethodTyInfo->getType()->getAs<FunctionType>()->getResultType()
!= Context.DependentTy;
+
+ TypeLoc TL = MethodTyInfo->getTypeLoc();
+ FunctionProtoTypeLoc Proto = cast<FunctionProtoTypeLoc>(TL);
+ Params = llvm::ArrayRef<ParmVarDecl *>(Proto.getParmArray(),
+ Proto.getNumArgs());
}
CXXMethodDecl *Method = startLambdaDefinition(Class, Intro.Range,
- MethodTyInfo, EndLoc);
+ MethodTyInfo, EndLoc, Params);
+
+ if (ExplicitParams)
+ CheckCXXDefaultArguments(Method);
// Attributes on the lambda apply to the method.
ProcessDeclAttributes(CurScope, Method, ParamInfo);
@@ -325,12 +336,8 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
}
finishLambdaExplicitCaptures(LSI);
- // Set the parameters on the decl, if specified.
- if (isa<FunctionProtoTypeLoc>(MethodTyInfo->getTypeLoc())) {
- FunctionProtoTypeLoc Proto
- = cast<FunctionProtoTypeLoc>(MethodTyInfo->getTypeLoc());
- addLambdaParameters(Method, CurScope, Proto.getParams());
- }
+ // Add lambda parameters into scope.
+ addLambdaParameters(Method, CurScope);
// Enter a new evaluation context to insulate the lambda from any
// cleanups from the enclosing full-expression.