Basic support for name mangling of C++11 lambda expressions. Because
name mangling in the Itanium C++ ABI for lambda expressions is so
dependent on context, we encode the number used to encode each lambda
as part of the lambda closure type, and maintain this value within
Sema.

Note that there are a several pieces still missing:
  - We still get the linkage of lambda expressions wrong
  - We aren't properly numbering or mangling lambda expressions that
  occur in default function arguments or in data member initializers.
  - We aren't (de-)serializing the lambda numbering tables




git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150982 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index cc651f9..e0056da 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -6748,6 +6748,13 @@
     + llvm::capacity_in_bytes(ClassScopeSpecializationPattern);
 }
 
+unsigned ASTContext::getLambdaManglingNumber(CXXMethodDecl *CallOperator) {
+  CXXRecordDecl *Lambda = CallOperator->getParent();
+  return LambdaMangleContexts[Lambda->getDeclContext()]
+           .getManglingNumber(CallOperator);
+}
+
+
 void ASTContext::setParameterIndex(const ParmVarDecl *D, unsigned int index) {
   ParamIndices[D] = index;
 }
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index 1f0100a..651bcc4 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -28,6 +28,7 @@
   InheritViz.cpp
   ItaniumCXXABI.cpp
   ItaniumMangle.cpp
+  LambdaMangleContext.cpp
   Mangle.cpp
   MicrosoftCXXABI.cpp
   MicrosoftMangle.cpp
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index f52f881..cbc5950 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -764,7 +764,8 @@
                        ArrayRef<Expr *> CaptureInits,
                        ArrayRef<VarDecl *> ArrayIndexVars,
                        ArrayRef<unsigned> ArrayIndexStarts,
-                       SourceLocation ClosingBrace)
+                       SourceLocation ClosingBrace,
+                       unsigned ManglingNumber)
   : Expr(LambdaExprClass, T, VK_RValue, OK_Ordinary,
          T->isDependentType(), T->isDependentType(), T->isDependentType(),
          /*ContainsUnexpandedParameterPack=*/false),
@@ -785,6 +786,7 @@
   ASTContext &Context = Class->getASTContext();
   Data.NumCaptures = NumCaptures;
   Data.NumExplicitCaptures = 0;
+  Data.ManglingNumber = ManglingNumber;
   Data.Captures = (Capture *)Context.Allocate(sizeof(Capture) * NumCaptures);
   Capture *ToCapture = Data.Captures;
   for (unsigned I = 0, N = Captures.size(); I != N; ++I) {
@@ -824,7 +826,8 @@
                                ArrayRef<Expr *> CaptureInits,
                                ArrayRef<VarDecl *> ArrayIndexVars,
                                ArrayRef<unsigned> ArrayIndexStarts,
-                               SourceLocation ClosingBrace) {
+                               SourceLocation ClosingBrace,
+                               unsigned ManglingNumber) {
   // Determine the type of the expression (i.e., the type of the
   // function object we're creating).
   QualType T = Context.getTypeDeclType(Class);
@@ -837,7 +840,7 @@
   return new (Mem) LambdaExpr(T, IntroducerRange, CaptureDefault, 
                               Captures, ExplicitParams, ExplicitResultType,
                               CaptureInits, ArrayIndexVars, ArrayIndexStarts,
-                              ClosingBrace);
+                              ClosingBrace, ManglingNumber);
 }
 
 LambdaExpr *LambdaExpr::CreateDeserialized(ASTContext &C, unsigned NumCaptures,
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 4843716..a0bb6c7 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -122,6 +122,13 @@
   }
 
   bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
+    // Lambda closure types with external linkage (indicated by a 
+    // non-zero lambda mangling number) have their own numbering scheme, so
+    // they do not need a discriminator.
+    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(ND))
+      if (RD->isLambda() && RD->getLambdaManglingNumber() > 0)
+        return false;
+        
     unsigned &discriminator = Uniquifier[ND];
     if (!discriminator)
       discriminator = ++Discriminator;
@@ -1076,6 +1083,38 @@
       break;
     }
 
+    // <unnamed-type-name> ::= <closure-type-name>
+    // 
+    // <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
+    // <lambda-sig> ::= <parameter-type>+   # Parameter types or 'v' for 'void'.
+    if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(TD)) {
+      if (Record->isLambda()) {
+        // FIXME: Figure out if we're in a function body, default argument,
+        // or initializer for a class member.
+        
+        Out << "Ul";
+        DeclarationName Name
+          = getASTContext().DeclarationNames.getCXXOperatorName(OO_Call);
+        const FunctionProtoType *Proto
+          = cast<CXXMethodDecl>(*Record->lookup(Name).first)->getType()->
+              getAs<FunctionProtoType>();
+        mangleBareFunctionType(Proto, /*MangleReturnType=*/false);        
+        Out << "E";
+        
+        // The number is omitted for the first closure type with a given 
+        // <lambda-sig> in a given context; it is n-2 for the nth closure type 
+        // (in lexical order) with that same <lambda-sig> and context.
+        //
+        // The AST keeps track of the number for us.
+        if (unsigned Number = Record->getLambdaManglingNumber()) {
+          if (Number > 1)
+            mangleNumber(Number - 2);
+        }
+        Out << '_';
+        break;
+      }
+    }
+        
     // Get a unique id for the anonymous struct.
     uint64_t AnonStructId = Context.getAnonymousStructId(TD);
 
diff --git a/lib/AST/LambdaMangleContext.cpp b/lib/AST/LambdaMangleContext.cpp
new file mode 100644
index 0000000..f5272a7
--- /dev/null
+++ b/lib/AST/LambdaMangleContext.cpp
@@ -0,0 +1,30 @@
+//===--- LambdaMangleContext.cpp - Context for mangling lambdas -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the LambdaMangleContext class, which keeps track of
+//  the Itanium C++ ABI mangling numbers for lambda expressions.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/AST/LambdaMangleContext.h"
+#include "clang/AST/DeclCXX.h"
+
+using namespace clang;
+
+unsigned LambdaMangleContext::getManglingNumber(CXXMethodDecl *CallOperator) {
+  const FunctionProtoType *Proto
+    = CallOperator->getType()->getAs<FunctionProtoType>();
+  ASTContext &Context = CallOperator->getASTContext();
+  
+  QualType Key = Context.getFunctionType(Context.VoidTy, 
+                                         Proto->arg_type_begin(),
+                                         Proto->getNumArgs(),
+                                         FunctionProtoType::ExtProtoInfo());
+  Key = Context.getCanonicalType(Key);
+  return ++ManglingNumbers[Key->castAs<FunctionProtoType>()];
+}