summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Decl.cpp36
1 files changed, 31 insertions, 5 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 57bf94c0f0b..a2bb440dbe7 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -1004,10 +1004,8 @@ static LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl,
else
return getLVForDecl(cast<NamedDecl>(ContextDecl), computation);
}
-
if (const NamedDecl *ND = dyn_cast<NamedDecl>(DC))
return getLVForDecl(ND, computation);
-
return LinkageInfo::external();
}
@@ -1092,6 +1090,19 @@ static LinkageInfo getLVForLocalDecl(const NamedDecl *D,
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<CXXRecordDecl>(
+ Record->getParent()->getParent());
+ }
+ return Ret;
+}
+
static LinkageInfo computeLVForDecl(const NamedDecl *D,
LVComputationKind computation) {
// Objective-C: treat all Objective-C declarations as having external
@@ -1122,9 +1133,24 @@ static LinkageInfo computeLVForDecl(const NamedDecl *D,
return LinkageInfo::internal();
}
- // This lambda has its linkage/visibility determined by its owner.
- return getLVForClosure(D->getDeclContext()->getRedeclContext(),
- Record->getLambdaContextDecl(), computation);
+ // 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->getLambdaManglingNumber())
+ return LinkageInfo::internal();
+
+ return getLVForClosure(
+ OuterMostLambda->getDeclContext()->getRedeclContext(),
+ OuterMostLambda->getLambdaContextDecl(), computation);
}
break;
OpenPOWER on IntegriCloud