diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-02-14 22:28:59 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-02-14 22:28:59 +0000 |
commit | c6889e7ed16604c51994e1f11becf213fdc64eb3 (patch) | |
tree | cd67da6857b1e624c3c190e4a9e3648c606381fb /lib/Sema/SemaLambda.cpp | |
parent | 57b9c4e9d85971e20ab0dac3eadabae672c43c62 (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.cpp | 49 |
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. |