diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/Sema/SemaLambda.cpp | 100 | ||||
| -rw-r--r-- | clang/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp | 9 |
2 files changed, 60 insertions, 49 deletions
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index ed05eff8e12..64fe7f7dcea 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -102,7 +102,6 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, /*isConstExpr=*/false, EndLoc); Method->setAccess(AS_public); - Class->addDecl(Method); // Temporarily set the lexical declaration context to the current // context, so that the Scope stack matches the lexical nesting. @@ -393,17 +392,63 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, CallOperator->setType(FunctionTy); } - // Finalize the lambda class. - SmallVector<Decl*, 4> Fields(Class->field_begin(), Class->field_end()); - ActOnFields(0, Class->getLocation(), Class, Fields, - SourceLocation(), SourceLocation(), 0); - CheckCompletedCXXClass(Class); + // 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 + // to pointer to function having the same parameter and return + // types as the closure type's function call operator. + if (Captures.empty() && CaptureDefault == LCD_None) { + const FunctionProtoType *Proto + = CallOperator->getType()->getAs<FunctionProtoType>(); + QualType FunctionPtrTy; + { + FunctionProtoType::ExtProtoInfo ExtInfo = Proto->getExtProtoInfo(); + ExtInfo.TypeQuals = 0; + QualType FunctionTy + = Context.getFunctionType(Proto->getResultType(), + Proto->arg_type_begin(), + Proto->getNumArgs(), + ExtInfo); + FunctionPtrTy = Context.getPointerType(FunctionTy); + } + + FunctionProtoType::ExtProtoInfo ExtInfo; + ExtInfo.TypeQuals = Qualifiers::Const; + QualType ConvTy = Context.getFunctionType(FunctionPtrTy, 0, 0, ExtInfo); + + SourceLocation Loc = IntroducerRange.getBegin(); + DeclarationName Name + = Context.DeclarationNames.getCXXConversionFunctionName( + Context.getCanonicalType(FunctionPtrTy)); + DeclarationNameLoc NameLoc; + NameLoc.NamedType.TInfo = Context.getTrivialTypeSourceInfo(FunctionPtrTy, + Loc); + CXXConversionDecl *Conversion + = CXXConversionDecl::Create(Context, Class, Loc, + DeclarationNameInfo(Name, Loc, NameLoc), + ConvTy, + Context.getTrivialTypeSourceInfo(ConvTy, + Loc), + /*isInline=*/false, /*isExplicit=*/false, + /*isConstexpr=*/false, Body->getLocEnd()); + Conversion->setAccess(AS_public); + Conversion->setImplicit(true); + Class->addDecl(Conversion); + } // C++ [expr.prim.lambda]p7: // The lambda-expression's compound-statement yields the // function-body (8.4) of the function call operator [...]. ActOnFinishFunctionBody(CallOperator, Body, /*IsInstantation=*/false); + + // Finalize the lambda class. + SmallVector<Decl*, 4> Fields(Class->field_begin(), Class->field_end()); CallOperator->setLexicalDeclContext(Class); + Class->addDecl(CallOperator); + ActOnFields(0, Class->getLocation(), Class, Fields, + SourceLocation(), SourceLocation(), 0); + CheckCompletedCXXClass(Class); + } if (LambdaExprNeedsCleanups) @@ -432,48 +477,5 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, break; } - // 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 - // to pointer to function having the same parameter and return - // types as the closure type's function call operator. - if (Captures.empty() && CaptureDefault == LCD_None) { - const FunctionProtoType *Proto - = CallOperator->getType()->getAs<FunctionProtoType>(); - QualType FunctionPtrTy; - { - FunctionProtoType::ExtProtoInfo ExtInfo = Proto->getExtProtoInfo(); - ExtInfo.TypeQuals = 0; - QualType FunctionTy - = Context.getFunctionType(Proto->getResultType(), - Proto->arg_type_begin(), - Proto->getNumArgs(), - ExtInfo); - FunctionPtrTy = Context.getPointerType(FunctionTy); - } - - FunctionProtoType::ExtProtoInfo ExtInfo; - ExtInfo.TypeQuals = Qualifiers::Const; - QualType ConvTy = Context.getFunctionType(FunctionPtrTy, 0, 0, ExtInfo); - - SourceLocation Loc = IntroducerRange.getBegin(); - DeclarationName Name - = Context.DeclarationNames.getCXXConversionFunctionName( - Context.getCanonicalType(FunctionPtrTy)); - DeclarationNameLoc NameLoc; - NameLoc.NamedType.TInfo = Context.getTrivialTypeSourceInfo(FunctionPtrTy, - Loc); - CXXConversionDecl *Conversion - = CXXConversionDecl::Create(Context, Class, Loc, - DeclarationNameInfo(Name, Loc, NameLoc), - ConvTy, - Context.getTrivialTypeSourceInfo(ConvTy, Loc), - /*isInline=*/false, /*isExplicit=*/false, - /*isConstexpr=*/false, Body->getLocEnd()); - Conversion->setAccess(AS_public); - Conversion->setImplicit(true); - Class->addDecl(Conversion); - } - return MaybeBindToTemporary(Lambda); } diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp index 21c8e22092b..8fa3837214d 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp @@ -43,3 +43,12 @@ void test_capture_constness(int i, const int ic) { } +struct S1 { + int x, y; + int operator()(int); + void f() { + [&]()->int { + return operator()(this->x + y); + }(); + } +}; |

