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
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index 7b729e7..867049d 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -13,6 +13,7 @@
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/Lookup.h"
+#include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Lex/Preprocessor.h"
@@ -482,6 +483,20 @@
   Class->addDecl(Conversion);
 }
 
+/// \brief Determine whether the given context is or is enclosed in an inline
+/// function.
+static bool isInInlineFunction(const DeclContext *DC) {
+  while (!DC->isFileContext()) {
+    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(DC))
+      if (FD->isInlined())
+        return true;
+    
+    DC = DC->getLexicalParent();
+  }
+  
+  return false;
+}
+         
 ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, 
                                  Scope *CurScope, 
                                  llvm::Optional<unsigned> ManglingNumber,
@@ -644,7 +659,8 @@
     enum ContextKind {
       Normal,
       DefaultArgument,
-      DataMember
+      DataMember,
+      StaticDataMember,
     } Kind = Normal;
 
     // Default arguments of member function parameters that appear in a class
@@ -658,7 +674,7 @@
             Kind = DefaultArgument;
       } else if (VarDecl *Var = dyn_cast<VarDecl>(ContextDecl)) {
         if (Var->getDeclContext()->isRecord())
-          Kind = DataMember;
+          Kind = StaticDataMember;
       } else if (isa<FieldDecl>(ContextDecl)) {
         Kind = DataMember;
       }
@@ -666,12 +682,25 @@
     
     switch (Kind) {
     case Normal:
-      ManglingNumber = Context.getLambdaManglingNumber(CallOperator);
-      ContextDecl = 0;
+      if (CurContext->isDependentContext() || isInInlineFunction(CurContext))
+        ManglingNumber = Context.getLambdaManglingNumber(CallOperator);
+      else
+        ManglingNumber = 0;
+        
+      // There is no special context for this lambda.
+      ContextDecl = 0;        
       break;
       
-    case DefaultArgument:
+    case StaticDataMember:
+      if (!CurContext->isDependentContext()) {
+        ManglingNumber = 0;
+        ContextDecl = 0;
+        break;
+      }
+      // Fall through to assign a mangling number.
+        
     case DataMember:
+    case DefaultArgument:
       ManglingNumber = ExprEvalContexts.back().getLambdaMangleContext()
                          .getManglingNumber(CallOperator);
       break;