From 9683f1de5f8eb3a4dd7c7fcb4ff58033b9cfa46f Mon Sep 17 00:00:00 2001 From: Faisal Vali Date: Thu, 3 Oct 2013 05:58:37 +0000 Subject: [PATCH] Revert changes from the nested lambdas commit till i figure out why the buildbots are failing. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@191876 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaTemplateInstantiate.cpp | 61 +-- lib/Sema/SemaTemplateInstantiateDecl.cpp | 24 - lib/Sema/TreeTransform.h | 95 +--- .../generic-lambda-unimplemented-1y.cpp | 17 + test/SemaCXX/cxx1y-generic-lambdas.cpp | 480 +----------------- 5 files changed, 48 insertions(+), 629 deletions(-) diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 29481d6c63..32111bac3a 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -14,7 +14,6 @@ #include "TreeTransform.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" -#include "clang/AST/ASTLambda.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/Basic/LangOptions.h" @@ -131,11 +130,6 @@ Sema::getTemplateInstantiationArgs(NamedDecl *D, assert(Function->getPrimaryTemplate() && "No function template?"); if (Function->getPrimaryTemplate()->isMemberSpecialization()) break; - - // If this function is a generic lambda specialization, we are done. - if (isGenericLambdaCallOperatorSpecialization(Function)) - break; - } else if (FunctionTemplateDecl *FunTmpl = Function->getDescribedFunctionTemplate()) { // Add the "injected" template arguments. @@ -917,56 +911,13 @@ namespace { } ExprResult TransformLambdaScope(LambdaExpr *E, - CXXMethodDecl *NewCallOperator) { - // If a lambda is undergoing transformation for instance in the - // call to foo('a') below: - // template void foo(T t) { - // auto L1 = [](T a) { return a; }; - // auto L2 = [](char b) { return b; }; - // auto L3 = [](auto c) { return c; }; - // } - // The AST nodes of the OldCallOperators within the primary template foo - // are connected to the NewCallOperators within the specialization of foo. - // - In the case of L1 and L2 we set the NewCallOperator to be considered - // an instantiation of the OldCallOperator. - // - In the generic lambda case, we set the NewTemplate to be considered - // an "instantiation" of the OldTemplate. - // See the documentation and use of get/setInstantiationOfMemberFunction - // and get/setInstantiatedFromMemberTemplate to appreciate the relevance - // of creating these links. - // And so it goes on and on with nested generic lambdas. - CXXMethodDecl *const OldCallOperator = E->getCallOperator(); - FunctionTemplateDecl *const NewCallOperatorTemplate = - NewCallOperator->getDescribedFunctionTemplate(); - FunctionTemplateDecl *const OldCallOperatorTemplate = - OldCallOperator->getDescribedFunctionTemplate(); - - if (!NewCallOperatorTemplate) - NewCallOperator->setInstantiationOfMemberFunction(OldCallOperator, - TSK_ImplicitInstantiation); - else { - NewCallOperatorTemplate->setInstantiatedFromMemberTemplate( - OldCallOperatorTemplate); - // Set this as a specialization so we don't go digging into the - // OldCallOperatorTemplate when retrieving the - // 'FunctionDecl::getTemplateInstantiationPattern()' - NewCallOperatorTemplate->setMemberSpecialization(); - } - return inherited::TransformLambdaScope(E, NewCallOperator); - } - TemplateParameterList *TransformTemplateParameterList( - TemplateParameterList *OrigTPL) { - TemplateParameterList *NewTPL = 0; - if (OrigTPL) { - if (!OrigTPL->size()) return OrigTPL; // size 0, do nothing - - DeclContext *Owner = OrigTPL->getParam(0)->getDeclContext(); - TemplateDeclInstantiator DeclInstantiator(getSema(), - /* DeclContext *Owner */ Owner, TemplateArgs); - NewTPL = DeclInstantiator.SubstTemplateParams(OrigTPL); - } - return NewTPL; + CXXMethodDecl *CallOperator) { + CallOperator->setInstantiationOfMemberFunction(E->getCallOperator(), + TSK_ImplicitInstantiation); + return TreeTransform:: + TransformLambdaScope(E, CallOperator); } + private: ExprResult transformNonTypeTemplateParmRef(NonTypeTemplateParmDecl *parm, SourceLocation loc, diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 359fb73166..35f3616db6 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4171,30 +4171,6 @@ DeclContext *Sema::FindInstantiatedContext(SourceLocation Loc, DeclContext* DC, NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, const MultiLevelTemplateArgumentList &TemplateArgs) { DeclContext *ParentDC = D->getDeclContext(); - - // If we have a parameter from a non-dependent context with a non-dependent - // type it obviously can not be mapped to a different instantiated decl. - // Consider the code below, with explicit return types, when N gets - // specialized ...: - // template void fooT(T t) { - // auto L = [](auto a) -> void { - // auto M = [](char b) -> void { - // auto N = [](auto c) -> void { - // int x = sizeof(a) + sizeof(b) + - // sizeof(c); - // }; - // N('a'); - // }; - // }; - // L(3.14); - // } - // fooT('a'); - // ... without this check below, findInstantiationOf fails with - // an assertion violation. - if (isa(D) && !ParentDC->isDependentContext() && - !cast(D)->getType()->isInstantiationDependentType()) - return D; - if (isa(D) || isa(D) || isa(D) || isa(D) || (ParentDC->isFunctionOrMethod() && ParentDC->isDependentContext()) || diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index bec956b6d7..977d0132b7 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -594,11 +594,6 @@ public: /// \brief Transform the captures and body of a lambda expression. ExprResult TransformLambdaScope(LambdaExpr *E, CXXMethodDecl *CallOperator); - TemplateParameterList *TransformTemplateParameterList( - TemplateParameterList *TPL) { - return TPL; - } - ExprResult TransformAddressOfOperand(Expr *E); ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E, bool IsAddressOfOperand); @@ -4578,19 +4573,6 @@ template QualType TreeTransform::TransformDecltypeType(TypeLocBuilder &TLB, DecltypeTypeLoc TL) { const DecltypeType *T = TL.getTypePtr(); - // Don't transform a decltype construct that has already been transformed - // into a non-dependent type. - // Allows the following to compile: - // auto L = [](auto a) { - // return [](auto b) ->decltype(a) { - // return b; - // }; - //}; - if (!T->isInstantiationDependentType()) { - DecltypeTypeLoc NewTL = TLB.push(TL.getType()); - NewTL.setNameLoc(TL.getNameLoc()); - return NewTL.getType(); - } // decltype expressions are not potentially evaluated contexts EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated, 0, @@ -8302,27 +8284,24 @@ template ExprResult TreeTransform::TransformLambdaExpr(LambdaExpr *E) { - getSema().PushLambdaScope(); - LambdaScopeInfo *LSI = getSema().getCurLambda(); - TemplateParameterList *const OrigTPL = E->getTemplateParameterList(); - TemplateParameterList *NewTPL = 0; - // Transform the template parameters, and add them to the - // current instantiation scope. - if (OrigTPL) { - NewTPL = getDerived().TransformTemplateParameterList(OrigTPL); - } - LSI->GLTemplateParameterList = NewTPL; - // Transform the type of the lambda parameters and start the definition of - // the lambda itself. - TypeSourceInfo *OldCallOpTSI = E->getCallOperator()->getTypeSourceInfo(); - TypeSourceInfo *NewCallOpTSI = TransformType(OldCallOpTSI); - if (!NewCallOpTSI) + // FIXME: Implement nested generic lambda transformations. + if (E->isGenericLambda()) { + getSema().Diag(E->getIntroducerRange().getBegin(), + diag::err_glambda_not_fully_implemented) + << " template transformation of generic lambdas not implemented yet"; + return ExprError(); + } + // Transform the type of the lambda parameters and start the definition of + // the lambda itself. + TypeSourceInfo *MethodTy + = TransformType(E->getCallOperator()->getTypeSourceInfo()); + if (!MethodTy) return ExprError(); // Create the local class that will describe the lambda. CXXRecordDecl *Class = getSema().createLambdaClosureType(E->getIntroducerRange(), - NewCallOpTSI, + MethodTy, /*KnownDependent=*/false); getDerived().transformedLocalDecl(E->getLambdaClass(), Class); @@ -8334,49 +8313,19 @@ TreeTransform::TransformLambdaExpr(LambdaExpr *E) { E->getCallOperator()->param_size(), 0, ParamTypes, &Params)) return ExprError(); - + getSema().PushLambdaScope(); + LambdaScopeInfo *LSI = getSema().getCurLambda(); + // TODO: Fix for nested lambdas + LSI->GLTemplateParameterList = 0; // Build the call operator. - CXXMethodDecl *NewCallOperator + CXXMethodDecl *CallOperator = getSema().startLambdaDefinition(Class, E->getIntroducerRange(), - NewCallOpTSI, + MethodTy, E->getCallOperator()->getLocEnd(), Params); - LSI->CallOperator = NewCallOperator; - // Fix the Decl Contexts of the parameters within the call op function - // prototype. - getDerived().transformAttrs(E->getCallOperator(), NewCallOperator); - - TypeLoc NewCallOpTL = NewCallOpTSI->getTypeLoc(); - FunctionProtoTypeLoc NewFPTL = NewCallOpTL.castAs(); - ParmVarDecl **NewParamDeclArray = NewFPTL.getParmArray(); - const unsigned NewNumArgs = NewFPTL.getNumArgs(); - for (unsigned I = 0; I < NewNumArgs; ++I) { - NewParamDeclArray[I]->setOwningFunction(NewCallOperator); - } - // If this is a non-generic lambda, the parameters do not get added to the - // current instantiation scope, so add them. This feels kludgey. - // Anyway, it allows the following to compile when the enclosing template - // is specialized and the entire lambda expression has to be - // transformed. Without this FindInstantiatedDecl causes an assertion. - // template void foo(T t) { - // auto L = [](auto a) { - // auto M = [](char b) { <-- note: non-generic lambda - // auto N = [](auto c) { - // int x = sizeof(a); - // x = sizeof(b); <-- specifically this line - // x = sizeof(c); - // }; - // }; - // }; - // } - // foo('a'); - // - if (!E->isGenericLambda()) { - for (unsigned I = 0; I < NewNumArgs; ++I) - SemaRef.CurrentInstantiationScope->InstantiatedLocal( - NewParamDeclArray[I], NewParamDeclArray[I]); - } - return getDerived().TransformLambdaScope(E, NewCallOperator); + getDerived().transformAttrs(E->getCallOperator(), CallOperator); + + return getDerived().TransformLambdaScope(E, CallOperator); } template diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/generic-lambda-unimplemented-1y.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/generic-lambda-unimplemented-1y.cpp index 92dd7ad187..a43a98bb18 100644 --- a/test/CXX/expr/expr.prim/expr.prim.lambda/generic-lambda-unimplemented-1y.cpp +++ b/test/CXX/expr/expr.prim/expr.prim.lambda/generic-lambda-unimplemented-1y.cpp @@ -29,3 +29,20 @@ void test() { } +namespace nested_generic_lambdas { +void test() { + auto L = [](auto a) -> int { + auto M = [](auto b, decltype(a) b2) -> int { //expected-error{{unimplemented}} + return 1; + }; + M(a, a); + }; + L(3); //expected-note{{in instantiation of}} +} +template void foo(T) { + auto L = [](auto a) { return a; }; //expected-error{{unimplemented}} +} +template void foo(int); //expected-note{{in instantiation of}} +} + + diff --git a/test/SemaCXX/cxx1y-generic-lambdas.cpp b/test/SemaCXX/cxx1y-generic-lambdas.cpp index c5da672f1d..b66825a536 100644 --- a/test/SemaCXX/cxx1y-generic-lambdas.cpp +++ b/test/SemaCXX/cxx1y-generic-lambdas.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -emit-llvm -o - %s +// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks %s // DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING // DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS // DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING @@ -99,8 +99,10 @@ void test() { //expected-note{{candidate}} } } + } + namespace return_type_deduction_ok { auto l = [](auto a) ->auto { return a; }(2); auto l2 = [](auto a) ->decltype(auto) { return a; }(2); @@ -112,479 +114,3 @@ namespace generic_lambda_as_default_argument_ok { void test(int i = [](auto a)->int { return a; }(3)) { } } - -namespace nested_non_capturing_lambda_tests { -template void print(Ts ...) { } -int test() { -{ - auto L = [](auto a) { - return [](auto b) { - return b; - }; - }; - auto M = L(3); - M(4.15); - } -{ - int i = 10; //expected-note{{declared here}} - auto L = [](auto a) { - return [](auto b) { //expected-note{{begins here}} - i = b; //expected-error{{cannot be implicitly captured}} - return b; - }; - }; - auto M = L(3); - M(4.15); //expected-note{{instantiation}} - } - { - auto L = [](auto a) { - print("a = ", a, "\n"); - return [](auto b) ->decltype(a) { - print("b = ", b, "\n"); - return b; - }; - }; - auto M = L(3); - M(4.15); - } - -{ - auto L = [](auto a) ->decltype(a) { - print("a = ", a, "\n"); - return [](auto b) ->decltype(a) { //expected-error{{no viable conversion}}\ - //expected-note{{candidate template ignored}} - print("b = ", b, "\n"); - return b; - }; - }; - auto M = L(3); //expected-note{{in instantiation of}} - } -{ - auto L = [](auto a) { - print("a = ", a, "\n"); - return [](auto ... b) ->decltype(a) { - print("b = ", b ..., "\n"); - return 4; - }; - }; - auto M = L(3); - M(4.15, 3, "fv"); -} - -{ - auto L = [](auto a) { - print("a = ", a, "\n"); - return [](auto ... b) ->decltype(a) { - print("b = ", b ..., "\n"); - return 4; - }; - }; - auto M = L(3); - int (*fp)(double, int, const char*) = M; - fp(4.15, 3, "fv"); -} - -{ - auto L = [](auto a) { - print("a = ", a, "\n"); - return [](char b) { - return [](auto ... c) ->decltype(b) { - print("c = ", c ..., "\n"); - return 42; - }; - }; - }; - L(4); - auto M = L(3); - M('a'); - auto N = M('x'); - N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); - char (*np)(const char*, int, const char*, double, const char*, int) = N; - np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); -} - - -{ - auto L = [](auto a) { - print("a = ", a, "\n"); - return [](decltype(a) b) { - return [](auto ... c) ->decltype(b) { - print("c = ", c ..., "\n"); - return 42; - }; - }; - }; - L('4'); - auto M = L('3'); - M('a'); - auto N = M('x'); - N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); - char (*np)(const char*, int, const char*, double, const char*, int) = N; - np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); -} - - -{ - struct X { - static void foo(double d) { } - void test() { - auto L = [](auto a) { - print("a = ", a, "\n"); - foo(a); - return [](decltype(a) b) { - foo(b); - foo(sizeof(a) + sizeof(b)); - return [](auto ... c) ->decltype(b) { - print("c = ", c ..., "\n"); - foo(decltype(b){}); - foo(sizeof(decltype(a)*) + sizeof(decltype(b)*)); - return 42; - }; - }; - }; - L('4'); - auto M = L('3'); - M('a'); - auto N = M('x'); - N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); - char (*np)(const char*, int, const char*, double, const char*, int) = N; - np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); - } -}; -X x; -x.test(); -} -// Make sure we can escape the function -{ - struct X { - static void foo(double d) { } - auto test() { - auto L = [](auto a) { - print("a = ", a, "\n"); - foo(a); - return [](decltype(a) b) { - foo(b); - foo(sizeof(a) + sizeof(b)); - return [](auto ... c) ->decltype(b) { - print("c = ", c ..., "\n"); - foo(decltype(b){}); - foo(sizeof(decltype(a)*) + sizeof(decltype(b)*)); - return 42; - }; - }; - }; - return L; - } -}; - X x; - auto L = x.test(); - L('4'); - auto M = L('3'); - M('a'); - auto N = M('x'); - N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); - char (*np)(const char*, int, const char*, double, const char*, int) = N; - np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); -} - -{ - struct X { - static void foo(double d) { } - auto test() { - auto L = [](auto a) { - print("a = ", a, "\n"); - foo(a); - return [](decltype(a) b) { - foo(b); - foo(sizeof(a) + sizeof(b)); - return [](auto ... c) { - print("c = ", c ..., "\n"); - foo(decltype(b){}); - foo(sizeof(decltype(a)*) + sizeof(decltype(b)*)); - return [](decltype(c) ... d) ->decltype(a) { //expected-note{{candidate}} - print("d = ", d ..., "\n"); - foo(decltype(b){}); - foo(sizeof(decltype(a)*) + sizeof(decltype(b)*)); - return decltype(a){}; - }; - }; - }; - }; - return L; - } -}; - X x; - auto L = x.test(); - L('4'); - auto M = L('3'); - M('a'); - auto N = M('x'); - auto O = N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); - char (*np)(const char*, int, const char*, double, const char*, int) = O; - np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); - int (*np2)(const char*, int, const char*, double, const char*, int) = O; // expected-error{{no viable conversion}} - -} -} // end test() - -namespace wrapped_within_templates { - -namespace explicit_return { -template int fooT(T t) { - auto L = [](auto a) -> void { - auto M = [](char b) -> void { - auto N = [](auto c) -> void { - int x = 0; - x = sizeof(a); - x = sizeof(b); - x = sizeof(c); - }; - N('a'); - N(decltype(a){}); - }; - }; - L(t); - L(3.14); - return 0; -} - -int run = fooT('a') + fooT(3.14); - -} // end explicit_return - -namespace implicit_return_deduction { -template auto fooT(T t) { - auto L = [](auto a) { - auto M = [](char b) { - auto N = [](auto c) { - int x = 0; - x = sizeof(a); - x = sizeof(b); - x = sizeof(c); - }; - N('a'); - N(decltype(a){}); - }; - }; - L(t); - L(3.14); - return 0; -} - -int run = fooT('a') + fooT(3.14); - -template void print(Ts ... ts) { } - -template using first = F; - -template auto fooV(Ts ... ts) { - auto L = [](auto ... a) { - auto M = [](decltype(a) ... b) { - auto N = [](auto c) { - int x = 0; - x = sizeof...(a); - x = sizeof...(b); - x = sizeof(c); - }; - N('a'); - N(N); - N(first{}); - }; - M(a...); - print("a = ", a..., "\n"); - }; - L(L, ts...); - print("ts = ", ts..., "\n"); - return 0; -} - -int run2 = fooV(3.14, " ", '4', 5) + fooV("BC", 3, 2.77, 'A', float{}, short{}, unsigned{}); - -} //implicit_return_deduction - - -} //wrapped_within_templates - -namespace at_ns_scope { - void foo(double d) { } - auto test() { - auto L = [](auto a) { - print("a = ", a, "\n"); - foo(a); - return [](decltype(a) b) { - foo(b); - foo(sizeof(a) + sizeof(b)); - return [](auto ... c) { - print("c = ", c ..., "\n"); - foo(decltype(b){}); - foo(sizeof(decltype(a)*) + sizeof(decltype(b)*)); - return [](decltype(c) ... d) ->decltype(a) { //expected-note{{candidate}} - print("d = ", d ..., "\n"); - foo(decltype(b){}); - foo(sizeof(decltype(a)*) + sizeof(decltype(b)*)); - return decltype(a){}; - }; - }; - }; - }; - return L; - } -auto L = test(); -auto L_test = L('4'); -auto M = L('3'); -auto M_test = M('a'); -auto N = M('x'); -auto O = N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); -char (*np)(const char*, int, const char*, double, const char*, int) = O; -auto NP_result = np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); -int (*np2)(const char*, int, const char*, double, const char*, int) = O; // expected-error{{no viable conversion}} - - - -} - -namespace variadic_tests_1 { -template void print(Ts ... ts) { } - -template using FirstType = F; -template F& FirstArg(F& f, Rest...) { return f; } - -template int fooV(Ts ... ts) { - auto L = [](auto ... a) -> void { - auto M = [](decltype(a) ... b) -> void { - auto N = [](auto c) -> void { - int x = 0; - x = sizeof...(a); - x = sizeof...(b); - x = sizeof(c); - }; - N('a'); - N(N); - N(FirstType{}); - }; - M(a...); - print("a = ", a..., "\n"); - }; - L(L, ts...); - print("ts = ", ts..., "\n"); - return 0; -} - -int run2 = fooV(3.14, " ", '4', 5) + fooV("BC", 3, 2.77, 'A', float{}, short{}, unsigned{}); - -namespace more_variadic_1 { - -template int fooV(Ts ... ts) { - auto L = [](auto ... a) { - auto M = [](decltype(a) ... b) -> void { - auto N = [](auto c) -> void { - int x = 0; - x = sizeof...(a); - x = sizeof...(b); - x = sizeof(c); - }; - N('a'); - N(N); - N(FirstType{}); - }; - M(a...); - return M; - }; - auto M = L(L, ts...); - decltype(L(L, ts...)) (*fp)(decltype(L), decltype(ts) ...) = L; - void (*fp2)(decltype(L), decltype(ts) ...) = L(L, ts...); - - { - auto L = [](auto ... a) { - auto M = [](decltype(a) ... b) { - auto N = [](auto c) -> void { - int x = 0; - x = sizeof...(a); - x = sizeof...(b); - x = sizeof(c); - }; - N('a'); - N(N); - N(FirstType{}); - return N; - }; - M(a...); - return M; - }; - auto M = L(L, ts...); - decltype(L(L, ts...)) (*fp)(decltype(L), decltype(ts) ...) = L; - fp(L, ts...); - decltype(L(L, ts...)(L, ts...)) (*fp2)(decltype(L), decltype(ts) ...) = L(L, ts...); - fp2 = fp(L, ts...); - void (*fp3)(char) = fp2(L, ts...); - fp3('a'); - } - return 0; -} - -int run2 = fooV(3.14, " ", '4', 5) + fooV("BC", 3, 2.77, 'A', float{}, short{}, unsigned{}); - - -} //end ns more_variadic_1 - -} // end ns variadic_tests_1 - -namespace at_ns_scope_within_class_member { - struct X { - static void foo(double d) { } - auto test() { - auto L = [](auto a) { - print("a = ", a, "\n"); - foo(a); - return [](decltype(a) b) { - foo(b); - foo(sizeof(a) + sizeof(b)); - return [](auto ... c) { - print("c = ", c ..., "\n"); - foo(decltype(b){}); - foo(sizeof(decltype(a)*) + sizeof(decltype(b)*)); - return [](decltype(c) ... d) ->decltype(a) { //expected-note{{candidate}} - print("d = ", d ..., "\n"); - foo(decltype(b){}); - foo(sizeof(decltype(a)*) + sizeof(decltype(b)*)); - return decltype(a){}; - }; - }; - }; - }; - return L; - } -}; -X x; -auto L = x.test(); -auto L_test = L('4'); -auto M = L('3'); -auto M_test = M('a'); -auto N = M('x'); -auto O = N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); -char (*np)(const char*, int, const char*, double, const char*, int) = O; -auto NP_result = np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); -int (*np2)(const char*, int, const char*, double, const char*, int) = O; // expected-error{{no viable conversion}} - -} //end at_ns_scope_within_class_member - - -namespace nested_generic_lambdas_123 { -void test() { - auto L = [](auto a) -> int { - auto M = [](auto b, decltype(a) b2) -> int { - return 1; - }; - M(a, a); - }; - L(3); -} -template void foo(T) { - auto L = [](auto a) { return a; }; -} -template void foo(int); -} // end ns nested_generic_lambdas_123 - - -} // end ns nested_non_capturing_lambda_tests - \ No newline at end of file -- 2.40.0