diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-02-21 04:17:39 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-02-21 04:17:39 +0000 |
commit | 5878cbcfaa90b8515550db86033fd5a0efab971d (patch) | |
tree | 7cb574e300ff00ea50204363fbc09578a8f8f9f9 /lib/AST/Decl.cpp | |
parent | 702afbc68b933af520420688cdf6783b411a8f70 (diff) |
Implement non-internal linkage for lambda closure types that need a
stable mangling, since these lambdas can end up in multiple
translation units. Sema is responsible for deciding when this is the
case, because it's already responsible for choosing the mangling
number.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151029 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Decl.cpp')
-rw-r--r-- | lib/AST/Decl.cpp | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index d80e06b322..4d1b562c59 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -734,6 +734,32 @@ static LinkageInfo getLVForDecl(const NamedDecl *D, LVFlags Flags) { case Decl::ObjCPropertyImpl: case Decl::ObjCProtocol: return LinkageInfo::external(); + + case Decl::CXXRecord: { + const CXXRecordDecl *Record = cast<CXXRecordDecl>(D); + if (Record->isLambda()) { + if (!Record->getLambdaManglingNumber()) { + // This lambda has no mangling number, so it's internal. + return LinkageInfo::internal(); + } + + // This lambda has its linkage/visibility determined by its owner. + const DeclContext *DC = D->getDeclContext()->getRedeclContext(); + if (Decl *ContextDecl = Record->getLambdaContextDecl()) { + if (isa<ParmVarDecl>(ContextDecl)) + DC = ContextDecl->getDeclContext()->getRedeclContext(); + else + return getLVForDecl(cast<NamedDecl>(ContextDecl), Flags); + } + + if (const NamedDecl *ND = dyn_cast<NamedDecl>(DC)) + return getLVForDecl(ND, Flags); + + return LinkageInfo::external(); + } + + break; + } } // Handle linkage for namespace-scope names. |