diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -1318,19 +1318,6 @@ LV.isVisibilityExplicit()); } -static inline const CXXRecordDecl* -getOutermostEnclosingLambda(const CXXRecordDecl *Record) { - const CXXRecordDecl *Ret = Record; - while (Record && Record->isLambda()) { - Ret = Record; - if (!Record->getParent()) break; - // Get the Containing Class of this Lambda Class - Record = dyn_cast_or_null( - Record->getParent()->getParent()); - } - return Ret; -} - LinkageInfo LinkageComputer::computeLVForDecl(const NamedDecl *D, LVComputationKind computation, bool IgnoreVarTypeLinkage) { @@ -1396,25 +1383,9 @@ return getInternalLinkageFor(D); } - // This lambda has its linkage/visibility determined: - // - either by the outermost lambda if that lambda has no mangling - // number. - // - or by the parent of the outer most lambda - // This prevents infinite recursion in settings such as nested lambdas - // used in NSDMI's, for e.g. - // struct L { - // int t{}; - // int t2 = ([](int a) { return [](int b) { return b; };})(t)(t); - // }; - const CXXRecordDecl *OuterMostLambda = - getOutermostEnclosingLambda(Record); - if (OuterMostLambda->hasKnownLambdaInternalLinkage() || - !OuterMostLambda->getLambdaManglingNumber()) - return getInternalLinkageFor(D); - return getLVForClosure( - OuterMostLambda->getDeclContext()->getRedeclContext(), - OuterMostLambda->getLambdaContextDecl(), computation); + Record->getDeclContext()->getRedeclContext(), + Record->getLambdaContextDecl(), computation); } break; diff --git a/clang/test/CodeGenCXX/lambda-expressions-nested-linkage.cpp b/clang/test/CodeGenCXX/lambda-expressions-nested-linkage.cpp --- a/clang/test/CodeGenCXX/lambda-expressions-nested-linkage.cpp +++ b/clang/test/CodeGenCXX/lambda-expressions-nested-linkage.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fblocks -emit-llvm -o - %s -fexceptions -std=c++11 | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fblocks -emit-llvm -o - %s -fexceptions -std=c++14 | FileCheck --check-prefixes=CHECK,CXX14 %s // CHECK-LABEL: define void @_ZN19non_inline_function3fooEv() // CHECK-LABEL: define internal void @"_ZZN19non_inline_function3fooEvENK3$_0clEi"(%class.anon @@ -51,3 +52,18 @@ } int use = foo(); } + +#if __cplusplus >= 201402L +// CXX14-LABEL: define internal void @"_ZZZN32lambda_capture_in_generic_lambda3fooIiEEDavENKUlT_E_clIZNS_L1fEvE3$_1EEDaS1_ENKUlvE_clEv" +namespace lambda_capture_in_generic_lambda { +template auto foo() { + return [](auto func) { + [func] { func(); }(); + }; +} +static void f() { + foo()([] { }); +} +void f1() { f(); } +} +#endif