<div dir="ltr">r185374.</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Jul 1, 2013 at 1:31 PM, Nico Weber <span dir="ltr"><<a href="mailto:thakis@chromium.org" target="_blank">thakis@chromium.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>bb-chapuni: build #2569 of ninja-clang-i686-msc17-R is complete: Failure [failed build_clang]  Build details are at <a href="http://bb.pgr.jp/builders/ninja-clang-i686-msc17-R/builds/2569" target="_blank">http://bb.pgr.jp/builders/ninja-clang-i686-msc17-R/builds/2569</a>  blamelist: Eli Friedman <<a href="mailto:eli.friedman@gmail.com" target="_blank">eli.friedman@gmail.com</a>></div>

<div>g++: /home/bb/cmake-clang-x86_64-linux/llvm-project/clang/lib/AST/LambdaMangleContext.cpp: No such file or directory</div><div>probably needs some cmake file update</div><div><br></div></div><div class="HOEnZb"><div class="h5">
<div class="gmail_extra">
<br><br><div class="gmail_quote">On Mon, Jul 1, 2013 at 1:22 PM, Eli Friedman <span dir="ltr"><<a href="mailto:eli.friedman@gmail.com" target="_blank">eli.friedman@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

Author: efriedma<br>
Date: Mon Jul  1 15:22:57 2013<br>
New Revision: 185372<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=185372&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=185372&view=rev</a><br>
Log:<br>
Fix mangling for block literals.<br>
<br>
Blocks, like lambdas, can be written in contexts which are required to be<br>
treated as the same under ODR.  Unlike lambdas, it isn't possible to actually<br>
take the address of a block, so the mangling of the block itself doesn't<br>
matter. However, objects like static variables inside a block do need to<br>
be mangled in a consistent way.<br>
<br>
There are basically three components here. One, block literals need a<br>
consistent numbering.  Two, objects/types inside a block literal need<br>
to be mangled using it.  Three, objects/types inside a block literal need<br>
to have their linkage computed correctly.<br>
<br>
Added:<br>
    cfe/trunk/include/clang/AST/MangleNumberingContext.h<br>
      - copied, changed from r185346, cfe/trunk/include/clang/AST/LambdaMangleContext.h<br>
    cfe/trunk/lib/AST/MangleNumberingContext.cpp<br>
      - copied, changed from r185346, cfe/trunk/lib/AST/LambdaMangleContext.cpp<br>
Removed:<br>
    cfe/trunk/include/clang/AST/LambdaMangleContext.h<br>
    cfe/trunk/lib/AST/LambdaMangleContext.cpp<br>
Modified:<br>
    cfe/trunk/include/clang/AST/ASTContext.h<br>
    cfe/trunk/include/clang/AST/Decl.h<br>
    cfe/trunk/include/clang/Sema/Sema.h<br>
    cfe/trunk/lib/AST/ASTContext.cpp<br>
    cfe/trunk/lib/AST/Decl.cpp<br>
    cfe/trunk/lib/AST/ItaniumMangle.cpp<br>
    cfe/trunk/lib/CodeGen/CGDecl.cpp<br>
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp<br>
    cfe/trunk/lib/CodeGen/CodeGenModule.h<br>
    cfe/trunk/lib/Sema/SemaExpr.cpp<br>
    cfe/trunk/lib/Sema/SemaLambda.cpp<br>
    cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/<a href="http://blocks-irgen.mm" target="_blank">blocks-irgen.mm</a><br>
    cfe/trunk/test/CodeGenObjCXX/<a href="http://mangle-blocks.mm" target="_blank">mangle-blocks.mm</a><br>
<br>
Modified: cfe/trunk/include/clang/AST/ASTContext.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=185372&r1=185371&r2=185372&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=185372&r1=185371&r2=185372&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/include/clang/AST/ASTContext.h (original)<br>
+++ cfe/trunk/include/clang/AST/ASTContext.h Mon Jul  1 15:22:57 2013<br>
@@ -19,7 +19,7 @@<br>
 #include "clang/AST/CanonicalType.h"<br>
 #include "clang/AST/CommentCommandTraits.h"<br>
 #include "clang/AST/Decl.h"<br>
-#include "clang/AST/LambdaMangleContext.h"<br>
+#include "clang/AST/MangleNumberingContext.h"<br>
 #include "clang/AST/NestedNameSpecifier.h"<br>
 #include "clang/AST/PrettyPrinter.h"<br>
 #include "clang/AST/RawCommentList.h"<br>
@@ -338,9 +338,11 @@ class ASTContext : public RefCountedBase<br>
   typedef llvm::TinyPtrVector<const CXXMethodDecl*> CXXMethodVector;<br>
   llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector> OverriddenMethods;<br>
<br>
-  /// \brief Mapping from each declaration context to its corresponding lambda<br>
-  /// mangling context.<br>
-  llvm::DenseMap<const DeclContext *, LambdaMangleContext> LambdaMangleContexts;<br>
+  /// \brief Mapping from each declaration context to its corresponding<br>
+  /// mangling numbering context (used for constructs like lambdas which<br>
+  /// need to be consistently numbered for the mangler).<br>
+  llvm::DenseMap<const DeclContext *, MangleNumberingContext><br>
+      MangleNumberingContexts;<br>
<br>
   llvm::DenseMap<const DeclContext *, unsigned> UnnamedMangleContexts;<br>
   llvm::DenseMap<const TagDecl *, unsigned> UnnamedMangleNumbers;<br>
@@ -2087,9 +2089,10 @@ public:<br>
   void addUnnamedTag(const TagDecl *Tag);<br>
   int getUnnamedTagManglingNumber(const TagDecl *Tag) const;<br>
<br>
-  /// \brief Retrieve the lambda mangling number for a lambda expression.<br>
-  unsigned getLambdaManglingNumber(CXXMethodDecl *CallOperator);<br>
-<br>
+  /// \brief Retrieve the context for computing mangling numbers in the given<br>
+  /// DeclContext.<br>
+  MangleNumberingContext &getManglingNumberContext(DeclContext *DC);<br>
+<br>
   /// \brief Used by ParmVarDecl to store on the side the<br>
   /// index of the parameter when it exceeds the size of the normal bitfield.<br>
   void setParameterIndex(const ParmVarDecl *D, unsigned index);<br>
<br>
Modified: cfe/trunk/include/clang/AST/Decl.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=185372&r1=185371&r2=185372&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=185372&r1=185371&r2=185372&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/include/clang/AST/Decl.h (original)<br>
+++ cfe/trunk/include/clang/AST/Decl.h Mon Jul  1 15:22:57 2013<br>
@@ -3115,13 +3115,17 @@ private:<br>
   Capture *Captures;<br>
   unsigned NumCaptures;<br>
<br>
+  unsigned ManglingNumber;<br>
+  Decl *ManglingContextDecl;<br>
+<br>
 protected:<br>
   BlockDecl(DeclContext *DC, SourceLocation CaretLoc)<br>
     : Decl(Block, DC, CaretLoc), DeclContext(Block),<br>
       IsVariadic(false), CapturesCXXThis(false),<br>
       BlockMissingReturnType(true), IsConversionFromLambda(false),<br>
       ParamInfo(0), NumParams(0), Body(0),<br>
-      SignatureAsWritten(0), Captures(0), NumCaptures(0) {}<br>
+      SignatureAsWritten(0), Captures(0), NumCaptures(0),<br>
+      ManglingNumber(0), ManglingContextDecl(0) {}<br>
<br>
 public:<br>
   static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L);<br>
@@ -3191,6 +3195,18 @@ public:<br>
                    const Capture *end,<br>
                    bool capturesCXXThis);<br>
<br>
+   unsigned getBlockManglingNumber() const {<br>
+     return ManglingNumber;<br>
+   }<br>
+   Decl *getBlockManglingContextDecl() const {<br>
+     return ManglingContextDecl;<br>
+   }<br>
+<br>
+  void setBlockMangling(unsigned Number, Decl *Ctx) {<br>
+    ManglingNumber = Number;<br>
+    ManglingContextDecl = Ctx;<br>
+  }<br>
+<br>
   virtual SourceRange getSourceRange() const LLVM_READONLY;<br>
<br>
   // Implement isa/cast/dyncast/etc.<br>
<br>
Removed: cfe/trunk/include/clang/AST/LambdaMangleContext.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/LambdaMangleContext.h?rev=185371&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/LambdaMangleContext.h?rev=185371&view=auto</a><br>


==============================================================================<br>
--- cfe/trunk/include/clang/AST/LambdaMangleContext.h (original)<br>
+++ cfe/trunk/include/clang/AST/LambdaMangleContext.h (removed)<br>
@@ -1,38 +0,0 @@<br>
-//===--- LambdaMangleContext.h - Context for mangling lambdas ---*- C++ -*-===//<br>
-//<br>
-//                     The LLVM Compiler Infrastructure<br>
-//<br>
-// This file is distributed under the University of Illinois Open Source<br>
-// License. See LICENSE.TXT for details.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-//<br>
-//  This file defines the LambdaMangleContext interface, which keeps track of<br>
-//  the Itanium C++ ABI mangling numbers for lambda expressions.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-#ifndef LLVM_CLANG_LAMBDAMANGLECONTEXT_H<br>
-#define LLVM_CLANG_LAMBDAMANGLECONTEXT_H<br>
-<br>
-#include "clang/Basic/LLVM.h"<br>
-#include "llvm/ADT/DenseMap.h"<br>
-#include "llvm/ADT/IntrusiveRefCntPtr.h"<br>
-<br>
-namespace clang {<br>
-<br>
-class CXXMethodDecl;<br>
-class FunctionProtoType;<br>
-<br>
-/// \brief Keeps track of the mangled names of lambda expressions within a<br>
-/// particular context.<br>
-class LambdaMangleContext : public RefCountedBase<LambdaMangleContext> {<br>
-  llvm::DenseMap<const FunctionProtoType *, unsigned> ManglingNumbers;<br>
-<br>
-public:<br>
-  /// \brief Retrieve the mangling number of a new lambda expression with the<br>
-  /// given call operator within this lambda context.<br>
-  unsigned getManglingNumber(CXXMethodDecl *CallOperator);<br>
-};<br>
-<br>
-} // end namespace clang<br>
-#endif<br>
<br>
Copied: cfe/trunk/include/clang/AST/MangleNumberingContext.h (from r185346, cfe/trunk/include/clang/AST/LambdaMangleContext.h)<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/MangleNumberingContext.h?p2=cfe/trunk/include/clang/AST/MangleNumberingContext.h&p1=cfe/trunk/include/clang/AST/LambdaMangleContext.h&r1=185346&r2=185372&rev=185372&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/MangleNumberingContext.h?p2=cfe/trunk/include/clang/AST/MangleNumberingContext.h&p1=cfe/trunk/include/clang/AST/LambdaMangleContext.h&r1=185346&r2=185372&rev=185372&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/include/clang/AST/LambdaMangleContext.h (original)<br>
+++ cfe/trunk/include/clang/AST/MangleNumberingContext.h Mon Jul  1 15:22:57 2013<br>
@@ -1,4 +1,4 @@<br>
-//===--- LambdaMangleContext.h - Context for mangling lambdas ---*- C++ -*-===//<br>
+//=== MangleNumberingContext.h - Context for mangling numbers ---*- C++ -*-===//<br>
 //<br>
 //                     The LLVM Compiler Infrastructure<br>
 //<br>
@@ -7,12 +7,13 @@<br>
 //<br>
 //===----------------------------------------------------------------------===//<br>
 //<br>
-//  This file defines the LambdaMangleContext interface, which keeps track of<br>
-//  the Itanium C++ ABI mangling numbers for lambda expressions.<br>
+//  This file defines the LambdaBlockMangleContext interface, which keeps track<br>
+//  of the Itanium C++ ABI mangling numbers for lambda expressions and block<br>
+//  literals.<br>
 //<br>
 //===----------------------------------------------------------------------===//<br>
-#ifndef LLVM_CLANG_LAMBDAMANGLECONTEXT_H<br>
-#define LLVM_CLANG_LAMBDAMANGLECONTEXT_H<br>
+#ifndef LLVM_CLANG_MANGLENUMBERINGCONTEXT_H<br>
+#define LLVM_CLANG_MANGLENUMBERINGCONTEXT_H<br>
<br>
 #include "clang/Basic/LLVM.h"<br>
 #include "llvm/ADT/DenseMap.h"<br>
@@ -20,18 +21,24 @@<br>
<br>
 namespace clang {<br>
<br>
+class BlockDecl;<br>
 class CXXMethodDecl;<br>
-class FunctionProtoType;<br>
+class Type;<br>
<br>
-/// \brief Keeps track of the mangled names of lambda expressions within a<br>
-/// particular context.<br>
-class LambdaMangleContext : public RefCountedBase<LambdaMangleContext> {<br>
-  llvm::DenseMap<const FunctionProtoType *, unsigned> ManglingNumbers;<br>
+/// \brief Keeps track of the mangled names of lambda expressions and block<br>
+/// literals within a particular context.<br>
+class MangleNumberingContext<br>
+    : public RefCountedBase<MangleNumberingContext> {<br>
+  llvm::DenseMap<const Type *, unsigned> ManglingNumbers;<br>
<br>
 public:<br>
   /// \brief Retrieve the mangling number of a new lambda expression with the<br>
-  /// given call operator within this lambda context.<br>
+  /// given call operator within this context.<br>
   unsigned getManglingNumber(CXXMethodDecl *CallOperator);<br>
+<br>
+  /// \brief Retrieve the mangling number of a new block literal within this<br>
+  /// context.<br>
+  unsigned getManglingNumber(BlockDecl *BD);<br>
 };<br>
<br>
 } // end namespace clang<br>
<br>
Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=185372&r1=185371&r2=185372&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=185372&r1=185371&r2=185372&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Jul  1 15:22:57 2013<br>
@@ -20,7 +20,7 @@<br>
 #include "clang/AST/Expr.h"<br>
 #include "clang/AST/ExprObjC.h"<br>
 #include "clang/AST/ExternalASTSource.h"<br>
-#include "clang/AST/LambdaMangleContext.h"<br>
+#include "clang/AST/MangleNumberingContext.h"<br>
 #include "clang/AST/NSAPI.h"<br>
 #include "clang/AST/PrettyPrinter.h"<br>
 #include "clang/AST/TypeLoc.h"<br>
@@ -662,17 +662,17 @@ public:<br>
     /// is indeed an unevaluated context.<br>
     SmallVector<LambdaExpr *, 2> Lambdas;<br>
<br>
-    /// \brief The declaration that provides context for the lambda expression<br>
-    /// if the normal declaration context does not suffice, e.g., in a<br>
-    /// default function argument.<br>
-    Decl *LambdaContextDecl;<br>
+    /// \brief The declaration that provides context for lambda expressions<br>
+    /// and block literals if the normal declaration context does not<br>
+    /// suffice, e.g., in a default function argument.<br>
+    Decl *ManglingContextDecl;<br>
<br>
     /// \brief The context information used to mangle lambda expressions<br>
-    /// within this context.<br>
+    /// and block literals within this context.<br>
     ///<br>
     /// This mangling information is allocated lazily, since most contexts<br>
-    /// do not have lambda expressions.<br>
-    IntrusiveRefCntPtr<LambdaMangleContext> LambdaMangle;<br>
+    /// do not have lambda expressions or block literals.<br>
+    IntrusiveRefCntPtr<MangleNumberingContext> MangleNumbering;<br>
<br>
     /// \brief If we are processing a decltype type, a set of call expressions<br>
     /// for which we have deferred checking the completeness of the return type.<br>
@@ -685,18 +685,19 @@ public:<br>
     ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context,<br>
                                       unsigned NumCleanupObjects,<br>
                                       bool ParentNeedsCleanups,<br>
-                                      Decl *LambdaContextDecl,<br>
+                                      Decl *ManglingContextDecl,<br>
                                       bool IsDecltype)<br>
       : Context(Context), ParentNeedsCleanups(ParentNeedsCleanups),<br>
         IsDecltype(IsDecltype), NumCleanupObjects(NumCleanupObjects),<br>
-        LambdaContextDecl(LambdaContextDecl), LambdaMangle() { }<br>
+        ManglingContextDecl(ManglingContextDecl), MangleNumbering() { }<br>
<br>
-    /// \brief Retrieve the mangling context for lambdas.<br>
-    LambdaMangleContext &getLambdaMangleContext() {<br>
-      assert(LambdaContextDecl && "Need to have a lambda context declaration");<br>
-      if (!LambdaMangle)<br>
-        LambdaMangle = new LambdaMangleContext;<br>
-      return *LambdaMangle;<br>
+    /// \brief Retrieve the mangling numbering context, used to consistently<br>
+    /// number constructs like lambdas for mangling.<br>
+    MangleNumberingContext &getMangleNumberingContext() {<br>
+      assert(ManglingContextDecl && "Need to have a context declaration");<br>
+      if (!MangleNumbering)<br>
+        MangleNumbering = new MangleNumberingContext;<br>
+      return *MangleNumbering;<br>
     }<br>
<br>
     bool isUnevaluated() const {<br>
@@ -707,6 +708,18 @@ public:<br>
   /// A stack of expression evaluation contexts.<br>
   SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts;<br>
<br>
+  /// \brief Compute the mangling number context for a lambda expression or<br>
+  /// block literal.<br>
+  ///<br>
+  /// \param DC - The DeclContext containing the lambda expression or<br>
+  /// block literal.<br>
+  /// \param[out] ManglingContextDecl - Returns the ManglingContextDecl<br>
+  /// associated with the context, if relevant.<br>
+  MangleNumberingContext *getCurrentMangleNumberContext(<br>
+    DeclContext *DC,<br>
+    Decl *&ManglingContextDecl);<br>
+<br>
+<br>
   /// SpecialMemberOverloadResult - The overloading result for a special member<br>
   /// function.<br>
   ///<br>
<br>
Modified: cfe/trunk/lib/AST/ASTContext.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=185372&r1=185371&r2=185372&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=185372&r1=185371&r2=185372&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/AST/ASTContext.cpp (original)<br>
+++ cfe/trunk/lib/AST/ASTContext.cpp Mon Jul  1 15:22:57 2013<br>
@@ -8007,13 +8007,10 @@ int ASTContext::getUnnamedTagManglingNum<br>
   return I != UnnamedMangleNumbers.end() ? I->second : -1;<br>
 }<br>
<br>
-unsigned ASTContext::getLambdaManglingNumber(CXXMethodDecl *CallOperator) {<br>
-  CXXRecordDecl *Lambda = CallOperator->getParent();<br>
-  return LambdaMangleContexts[Lambda->getDeclContext()]<br>
-           .getManglingNumber(CallOperator);<br>
+MangleNumberingContext &ASTContext::getManglingNumberContext(DeclContext *DC) {<br>
+  return MangleNumberingContexts[DC];<br>
 }<br>
<br>
-<br>
 void ASTContext::setParameterIndex(const ParmVarDecl *D, unsigned int index) {<br>
   ParamIndices[D] = index;<br>
 }<br>
<br>
Modified: cfe/trunk/lib/AST/Decl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=185372&r1=185371&r2=185372&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=185372&r1=185371&r2=185372&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/AST/Decl.cpp (original)<br>
+++ cfe/trunk/lib/AST/Decl.cpp Mon Jul  1 15:22:57 2013<br>
@@ -287,13 +287,12 @@ getLVForTemplateParameterList(const Temp<br>
 static LinkageInfo getLVForDecl(const NamedDecl *D,<br>
                                 LVComputationKind computation);<br>
<br>
-static const FunctionDecl *getOutermostFunctionContext(const Decl *D) {<br>
-  const FunctionDecl *Ret = NULL;<br>
+static const Decl *getOutermostFuncOrBlockContext(const Decl *D) {<br>
+  const Decl *Ret = NULL;<br>
   const DeclContext *DC = D->getDeclContext();<br>
   while (DC->getDeclKind() != Decl::TranslationUnit) {<br>
-    const FunctionDecl *F = dyn_cast<FunctionDecl>(DC);<br>
-    if (F)<br>
-      Ret = F;<br>
+    if (isa<FunctionDecl>(DC) || isa<BlockDecl>(DC))<br>
+      Ret = cast<Decl>(DC);<br>
     DC = DC->getParent();<br>
   }<br>
   return Ret;<br>
@@ -996,6 +995,22 @@ NamedDecl::getExplicitVisibility(Explici<br>
   return None;<br>
 }<br>
<br>
+static LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl,<br>
+                                   LVComputationKind computation) {<br>
+  // This lambda has its linkage/visibility determined by its owner.<br>
+  if (ContextDecl) {<br>
+    if (isa<ParmVarDecl>(ContextDecl))<br>
+      DC = ContextDecl->getDeclContext()->getRedeclContext();<br>
+    else<br>
+      return getLVForDecl(cast<NamedDecl>(ContextDecl), computation);<br>
+  }<br>
+<br>
+  if (const NamedDecl *ND = dyn_cast<NamedDecl>(DC))<br>
+    return getLVForDecl(ND, computation);<br>
+<br>
+  return LinkageInfo::external();<br>
+}<br>
+<br>
 static LinkageInfo getLVForLocalDecl(const NamedDecl *D,<br>
                                      LVComputationKind computation) {<br>
   if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {<br>
@@ -1052,14 +1067,25 @@ static LinkageInfo getLVForLocalDecl(con<br>
   if (!Context.getLangOpts().CPlusPlus)<br>
     return LinkageInfo::none();<br>
<br>
-  const FunctionDecl *FD = getOutermostFunctionContext(D);<br>
-  if (!FD)<br>
+  const Decl *OuterD = getOutermostFuncOrBlockContext(D);<br>
+  if (!OuterD)<br>
     return LinkageInfo::none();<br>
<br>
-  if (!FD->isInlined() && FD->getTemplateSpecializationKind() == TSK_Undeclared)<br>
-    return LinkageInfo::none();<br>
+  LinkageInfo LV;<br>
+  if (const BlockDecl *BD = dyn_cast<BlockDecl>(OuterD)) {<br>
+    if (!BD->getBlockManglingNumber())<br>
+      return LinkageInfo::none();<br>
+<br>
+    LV = getLVForClosure(BD->getDeclContext()->getRedeclContext(),<br>
+                         BD->getBlockManglingContextDecl(), computation);<br>
+  } else {<br>
+    const FunctionDecl *FD = cast<FunctionDecl>(OuterD);<br>
+    if (!FD->isInlined() &&<br>
+        FD->getTemplateSpecializationKind() == TSK_Undeclared)<br>
+      return LinkageInfo::none();<br>
<br>
-  LinkageInfo LV = getLVForDecl(FD, computation);<br>
+    LV = getLVForDecl(FD, computation);<br>
+  }<br>
   if (!isExternallyVisible(LV.getLinkage()))<br>
     return LinkageInfo::none();<br>
   return LinkageInfo(VisibleNoLinkage, LV.getVisibility(),<br>
@@ -1095,20 +1121,10 @@ static LinkageInfo computeLVForDecl(cons<br>
           // This lambda has no mangling number, so it's internal.<br>
           return LinkageInfo::internal();<br>
         }<br>
-<br>
-        // This lambda has its linkage/visibility determined by its owner.<br>
-        const DeclContext *DC = D->getDeclContext()->getRedeclContext();<br>
-        if (Decl *ContextDecl = Record->getLambdaContextDecl()) {<br>
-          if (isa<ParmVarDecl>(ContextDecl))<br>
-            DC = ContextDecl->getDeclContext()->getRedeclContext();<br>
-          else<br>
-            return getLVForDecl(cast<NamedDecl>(ContextDecl), computation);<br>
-        }<br>
<br>
-        if (const NamedDecl *ND = dyn_cast<NamedDecl>(DC))<br>
-          return getLVForDecl(ND, computation);<br>
-<br>
-        return LinkageInfo::external();<br>
+        // This lambda has its linkage/visibility determined by its owner.<br>
+        return getLVForClosure(D->getDeclContext()->getRedeclContext(),<br>
+                               Record->getLambdaContextDecl(), computation);<br>
       }<br>
<br>
       break;<br>
<br>
Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=185372&r1=185371&r2=185372&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=185372&r1=185371&r2=185372&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)<br>
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Mon Jul  1 15:22:57 2013<br>
@@ -1416,15 +1416,22 @@ void CXXNameMangler::manglePrefix(const<br>
     return;<br>
<br>
   if (const BlockDecl *Block = dyn_cast<BlockDecl>(DC)) {<br>
-    // The symbol we're adding a prefix for isn't externally<br>
-    // visible; make up something sane.<br>
-    // FIXME: This isn't always true!<br>
-    SmallString<16> BlockPrefix;<br>
-    BlockPrefix += "__block_prefix_internal";<br>
-    unsigned Number = Context.getBlockId(Block, false);<br>
+    // Reflect the lambda mangling rules, except that we don't have an<br>
+    // actual function declaration.<br>
+    if (NoFunction)<br>
+      return;<br>
+<br>
+    manglePrefix(getEffectiveParentContext(DC), NoFunction);<br>
+    // If we have a block mangling number, use it.<br>
+    unsigned Number = Block->getBlockManglingNumber();<br>
+    // Otherwise, just make up a number. It doesn't matter what it is because<br>
+    // the symbol in question isn't externally visible.<br>
+    if (!Number)<br>
+      Number = Context.getBlockId(Block, false);<br>
+    Out << "Ub";<br>
     if (Number > 1)<br>
-      BlockPrefix += llvm::utostr_32(Number - 2);<br>
-    Out << BlockPrefix.size() << BlockPrefix;<br>
+      Out << Number - 2;<br>
+    Out << '_';<br>
     return;<br>
   } else if (isa<CapturedDecl>(DC)) {<br>
     // Skip CapturedDecl context.<br>
<br>
Removed: cfe/trunk/lib/AST/LambdaMangleContext.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/LambdaMangleContext.cpp?rev=185371&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/LambdaMangleContext.cpp?rev=185371&view=auto</a><br>


==============================================================================<br>
--- cfe/trunk/lib/AST/LambdaMangleContext.cpp (original)<br>
+++ cfe/trunk/lib/AST/LambdaMangleContext.cpp (removed)<br>
@@ -1,30 +0,0 @@<br>
-//===--- LambdaMangleContext.cpp - Context for mangling lambdas -*- C++ -*-===//<br>
-//<br>
-//                     The LLVM Compiler Infrastructure<br>
-//<br>
-// This file is distributed under the University of Illinois Open Source<br>
-// License. See LICENSE.TXT for details.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-//<br>
-//  This file defines the LambdaMangleContext class, which keeps track of<br>
-//  the Itanium C++ ABI mangling numbers for lambda expressions.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-<br>
-#include "clang/AST/LambdaMangleContext.h"<br>
-#include "clang/AST/ASTContext.h"<br>
-#include "clang/AST/DeclCXX.h"<br>
-<br>
-using namespace clang;<br>
-<br>
-unsigned LambdaMangleContext::getManglingNumber(CXXMethodDecl *CallOperator) {<br>
-  const FunctionProtoType *Proto<br>
-    = CallOperator->getType()->getAs<FunctionProtoType>();<br>
-  ASTContext &Context = CallOperator->getASTContext();<br>
-<br>
-  QualType Key = Context.getFunctionType(Context.VoidTy, Proto->getArgTypes(),<br>
-                                         FunctionProtoType::ExtProtoInfo());<br>
-  Key = Context.getCanonicalType(Key);<br>
-  return ++ManglingNumbers[Key->castAs<FunctionProtoType>()];<br>
-}<br>
<br>
Copied: cfe/trunk/lib/AST/MangleNumberingContext.cpp (from r185346, cfe/trunk/lib/AST/LambdaMangleContext.cpp)<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MangleNumberingContext.cpp?p2=cfe/trunk/lib/AST/MangleNumberingContext.cpp&p1=cfe/trunk/lib/AST/LambdaMangleContext.cpp&r1=185346&r2=185372&rev=185372&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MangleNumberingContext.cpp?p2=cfe/trunk/lib/AST/MangleNumberingContext.cpp&p1=cfe/trunk/lib/AST/LambdaMangleContext.cpp&r1=185346&r2=185372&rev=185372&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/AST/LambdaMangleContext.cpp (original)<br>
+++ cfe/trunk/lib/AST/MangleNumberingContext.cpp Mon Jul  1 15:22:57 2013<br>
@@ -1,4 +1,4 @@<br>
-//===--- LambdaMangleContext.cpp - Context for mangling lambdas -*- C++ -*-===//<br>
+//===--- MangleNumberingContext.cpp - Context for mangling numbers --------===//<br>
 //<br>
 //                     The LLVM Compiler Infrastructure<br>
 //<br>
@@ -12,13 +12,14 @@<br>
 //<br>
 //===----------------------------------------------------------------------===//<br>
<br>
-#include "clang/AST/LambdaMangleContext.h"<br>
+#include "clang/AST/MangleNumberingContext.h"<br>
 #include "clang/AST/ASTContext.h"<br>
 #include "clang/AST/DeclCXX.h"<br>
<br>
 using namespace clang;<br>
<br>
-unsigned LambdaMangleContext::getManglingNumber(CXXMethodDecl *CallOperator) {<br>
+unsigned<br>
+MangleNumberingContext::getManglingNumber(CXXMethodDecl *CallOperator) {<br>
   const FunctionProtoType *Proto<br>
     = CallOperator->getType()->getAs<FunctionProtoType>();<br>
   ASTContext &Context = CallOperator->getASTContext();<br>
@@ -28,3 +29,10 @@ unsigned LambdaMangleContext::getManglin<br>
   Key = Context.getCanonicalType(Key);<br>
   return ++ManglingNumbers[Key->castAs<FunctionProtoType>()];<br>
 }<br>
+<br>
+unsigned<br>
+MangleNumberingContext::getManglingNumber(BlockDecl *BD) {<br>
+  // FIXME: Compute a BlockPointerType?  Not obvious how.<br>
+  const Type *Ty = 0;<br>
+  return ++ManglingNumbers[Ty];<br>
+}<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=185372&r1=185371&r2=185372&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=185372&r1=185371&r2=185372&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Mon Jul  1 15:22:57 2013<br>
@@ -130,9 +130,27 @@ void CodeGenFunction::EmitVarDecl(const<br>
     if (D.isExternallyVisible()) {<br>
       const Decl *D = CurCodeDecl;<br>
       while (true) {<br>
-        if (isa<BlockDecl>(D)) {<br>
-          // FIXME: Handle this case properly!  (Should be similar to the<br>
-          // way we handle lambdas in computeLVForDecl in Decl.cpp.)<br>
+        if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {<br>
+          if (!BD->getBlockManglingNumber())<br>
+            break;<br>
+<br>
+          // This block has the linkage/visibility of its contained variables<br>
+          // determined by its owner.<br>
+          const DeclContext *DC = D->getDeclContext()->getRedeclContext();<br>
+          if (Decl *ContextDecl = BD->getBlockManglingContextDecl()) {<br>
+            if (isa<ParmVarDecl>(ContextDecl)) {<br>
+              DC = ContextDecl->getDeclContext()->getRedeclContext();<br>
+            } else {<br>
+              D = ContextDecl;<br>
+              continue;<br>
+            }<br>
+          }<br>
+<br>
+          if (const NamedDecl *ND = dyn_cast<NamedDecl>(DC)) {<br>
+            D = ND;<br>
+            continue;<br>
+          }<br>
+<br>
           break;<br>
         } else if (isa<CapturedDecl>(D)) {<br>
           D = cast<Decl>(cast<CapturedDecl>(D)->getParent());<br>
@@ -140,13 +158,26 @@ void CodeGenFunction::EmitVarDecl(const<br>
           break;<br>
         }<br>
       }<br>
-      // FIXME: Do we really only care about FunctionDecls here?<br>
+      llvm::GlobalValue::LinkageTypes ParentLinkage;<br>
       if (isa<FunctionDecl>(D)) {<br>
-        llvm::GlobalValue::LinkageTypes ParentLinkage =<br>
-            CGM.getFunctionLinkage(cast<FunctionDecl>(D));<br>
-        if (llvm::GlobalValue::isWeakForLinker(ParentLinkage))<br>
-          Linkage = ParentLinkage;<br>
+        ParentLinkage = CGM.getFunctionLinkage(cast<FunctionDecl>(D));<br>
+      } else if (isa<VarDecl>(D)) {<br>
+        // FIXME: I'm pretty sure this is wrong...<br>
+        ParentLinkage = CGM.GetLLVMLinkageVarDefinition(cast<VarDecl>(D),<br>
+                                                        /*constant*/false);<br>
+      } else {<br>
+        assert(isa<FieldDecl>(D) && "Expect function, variable, or field");<br>
+        // FIXME: Is this right?<br>
+        ParentLinkage = llvm::GlobalValue::LinkOnceODRLinkage;<br>
       }<br>
+<br>
+      if (llvm::GlobalValue::isWeakForLinker(ParentLinkage))<br>
+        Linkage = ParentLinkage;<br>
+<br>
+      // FIXME: We need to force the emission/use of a guard variable for<br>
+      // some variables even if we can constant-evaluate them because<br>
+      // we can't guarantee every translation unit will constant-evaluate them.<br>
+      // Also, we might need to fix up the linkage.<br>
     }<br>
<br>
     return EmitStaticVarDecl(D, Linkage);<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=185372&r1=185371&r2=185372&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=185372&r1=185371&r2=185372&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Mon Jul  1 15:22:57 2013<br>
@@ -1797,7 +1797,7 @@ void CodeGenModule::EmitGlobalVarDefinit<br>
<br>
   // Set the llvm linkage type as appropriate.<br>
   llvm::GlobalValue::LinkageTypes Linkage =<br>
-    GetLLVMLinkageVarDefinition(D, GV);<br>
+    GetLLVMLinkageVarDefinition(D, GV->isConstant());<br>
   GV->setLinkage(Linkage);<br>
   if (Linkage == llvm::GlobalVariable::CommonLinkage)<br>
     // common vars aren't constant even if declared const.<br>
@@ -1828,8 +1828,7 @@ void CodeGenModule::EmitGlobalVarDefinit<br>
 }<br>
<br>
 llvm::GlobalValue::LinkageTypes<br>
-CodeGenModule::GetLLVMLinkageVarDefinition(const VarDecl *D,<br>
-                                           llvm::GlobalVariable *GV) {<br>
+CodeGenModule::GetLLVMLinkageVarDefinition(const VarDecl *D, bool isConstant) {<br>
   GVALinkage Linkage = getContext().GetGVALinkageForVariable(D);<br>
   if (Linkage == GVA_Internal)<br>
     return llvm::Function::InternalLinkage;<br>
@@ -1844,7 +1843,7 @@ CodeGenModule::GetLLVMLinkageVarDefiniti<br>
     // <a href="http://msdn.microsoft.com/en-us/library/5tkz6s71.aspx" target="_blank">http://msdn.microsoft.com/en-us/library/5tkz6s71.aspx</a><br>
     return llvm::GlobalVariable::WeakODRLinkage;<br>
   } else if (D->hasAttr<WeakAttr>()) {<br>
-    if (GV->isConstant())<br>
+    if (isConstant)<br>
       return llvm::GlobalVariable::WeakODRLinkage;<br>
     else<br>
       return llvm::GlobalVariable::WeakAnyLinkage;<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=185372&r1=185371&r2=185372&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=185372&r1=185371&r2=185372&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)<br>
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Mon Jul  1 15:22:57 2013<br>
@@ -942,8 +942,7 @@ public:<br>
   /// GetLLVMLinkageVarDefinition - Returns LLVM linkage for a global<br>
   /// variable.<br>
   llvm::GlobalValue::LinkageTypes<br>
-  GetLLVMLinkageVarDefinition(const VarDecl *D,<br>
-                              llvm::GlobalVariable *GV);<br>
+  GetLLVMLinkageVarDefinition(const VarDecl *D, bool isConstant);<br>
<br>
   /// Emit all the global annotations.<br>
   void EmitGlobalAnnotations();<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=185372&r1=185371&r2=185372&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=185372&r1=185371&r2=185372&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jul  1 15:22:57 2013<br>
@@ -9810,6 +9810,17 @@ ExprResult Sema::ActOnChooseExpr(SourceL<br>
 /// ActOnBlockStart - This callback is invoked when a block literal is started.<br>
 void Sema::ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope) {<br>
   BlockDecl *Block = BlockDecl::Create(Context, CurContext, CaretLoc);<br>
+<br>
+  {<br>
+    Decl *ManglingContextDecl;<br>
+    if (MangleNumberingContext *MCtx =<br>
+            getCurrentMangleNumberContext(Block->getDeclContext(),<br>
+                                          ManglingContextDecl)) {<br>
+      unsigned ManglingNumber = MCtx->getManglingNumber(Block);<br>
+      Block->setBlockMangling(ManglingNumber, ManglingContextDecl);<br>
+    }<br>
+  }<br>
+<br>
   PushBlockScope(CurScope, Block);<br>
   CurContext->addDecl(Block);<br>
   if (CurScope)<br>
@@ -9929,11 +9940,7 @@ void Sema::ActOnBlockArguments(SourceLoc<br>
   // Finally we can process decl attributes.<br>
   ProcessDeclAttributes(CurScope, CurBlock->TheDecl, ParamInfo);<br>
<br>
-  // Put the parameter variables in scope.  We can bail out immediately<br>
-  // if we don't have any.<br>
-  if (Params.empty())<br>
-    return;<br>
-<br>
+  // Put the parameter variables in scope.<br>
   for (BlockDecl::param_iterator AI = CurBlock->TheDecl->param_begin(),<br>
          E = CurBlock->TheDecl->param_end(); AI != E; ++AI) {<br>
     (*AI)->setOwningFunction(CurBlock->TheDecl);<br>
@@ -10641,8 +10648,8 @@ void<br>
 Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext,<br>
                                       ReuseLambdaContextDecl_t,<br>
                                       bool IsDecltype) {<br>
-  Decl *LambdaContextDecl = ExprEvalContexts.back().LambdaContextDecl;<br>
-  PushExpressionEvaluationContext(NewContext, LambdaContextDecl, IsDecltype);<br>
+  Decl *ClosureContextDecl = ExprEvalContexts.back().ManglingContextDecl;<br>
+  PushExpressionEvaluationContext(NewContext, ClosureContextDecl, IsDecltype);<br>
 }<br>
<br>
 void Sema::PopExpressionEvaluationContext() {<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaLambda.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=185372&r1=185371&r2=185372&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=185372&r1=185371&r2=185372&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaLambda.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaLambda.cpp Mon Jul  1 15:22:57 2013<br>
@@ -52,6 +52,72 @@ static bool isInInlineFunction(const Dec<br>
   return false;<br>
 }<br>
<br>
+MangleNumberingContext *<br>
+Sema::getCurrentMangleNumberContext(DeclContext *DC,<br>
+                                    Decl *&ManglingContextDecl) {<br>
+  // Compute the context for allocating mangling numbers in the current<br>
+  // expression, if the ABI requires them.<br>
+  ManglingContextDecl = ExprEvalContexts.back().ManglingContextDecl;<br>
+<br>
+  enum ContextKind {<br>
+    Normal,<br>
+    DefaultArgument,<br>
+    DataMember,<br>
+    StaticDataMember<br>
+  } Kind = Normal;<br>
+<br>
+  // Default arguments of member function parameters that appear in a class<br>
+  // definition, as well as the initializers of data members, receive special<br>
+  // treatment. Identify them.<br>
+  if (ManglingContextDecl) {<br>
+    if (ParmVarDecl *Param = dyn_cast<ParmVarDecl>(ManglingContextDecl)) {<br>
+      if (const DeclContext *LexicalDC<br>
+          = Param->getDeclContext()->getLexicalParent())<br>
+        if (LexicalDC->isRecord())<br>
+          Kind = DefaultArgument;<br>
+    } else if (VarDecl *Var = dyn_cast<VarDecl>(ManglingContextDecl)) {<br>
+      if (Var->getDeclContext()->isRecord())<br>
+        Kind = StaticDataMember;<br>
+    } else if (isa<FieldDecl>(ManglingContextDecl)) {<br>
+      Kind = DataMember;<br>
+    }<br>
+  }<br>
+<br>
+  // Itanium ABI [5.1.7]:<br>
+  //   In the following contexts [...] the one-definition rule requires closure<br>
+  //   types in different translation units to "correspond":<br>
+  bool IsInNonspecializedTemplate =<br>
+    !ActiveTemplateInstantiations.empty() || CurContext->isDependentContext();<br>
+  switch (Kind) {<br>
+  case Normal:<br>
+    //  -- the bodies of non-exported nonspecialized template functions<br>
+    //  -- the bodies of inline functions<br>
+    if ((IsInNonspecializedTemplate &&<br>
+         !(ManglingContextDecl && isa<ParmVarDecl>(ManglingContextDecl))) ||<br>
+        isInInlineFunction(CurContext)) {<br>
+      ManglingContextDecl = 0;<br>
+      return &Context.getManglingNumberContext(DC);<br>
+    }<br>
+<br>
+    ManglingContextDecl = 0;<br>
+    return 0;<br>
+<br>
+  case StaticDataMember:<br>
+    //  -- the initializers of nonspecialized static members of template classes<br>
+    if (!IsInNonspecializedTemplate) {<br>
+      ManglingContextDecl = 0;<br>
+      return 0;<br>
+    }<br>
+    // Fall through to get the current context.<br>
+<br>
+  case DataMember:<br>
+    //  -- the in-class initializers of class members<br>
+  case DefaultArgument:<br>
+    //  -- default arguments appearing in class definitions<br>
+    return &ExprEvalContexts.back().getMangleNumberingContext();<br>
+  }<br>
+}<br>
+<br>
 CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class,<br>
                  SourceRange IntroducerRange,<br>
                  TypeSourceInfo *MethodType,<br>
@@ -98,75 +164,14 @@ CXXMethodDecl *Sema::startLambdaDefiniti<br>
       (*P)->setOwningFunction(Method);<br>
   }<br>
<br>
-  // Allocate a mangling number for this lambda expression, if the ABI<br>
-  // requires one.<br>
-  Decl *ContextDecl = ExprEvalContexts.back().LambdaContextDecl;<br>
-<br>
-  enum ContextKind {<br>
-    Normal,<br>
-    DefaultArgument,<br>
-    DataMember,<br>
-    StaticDataMember<br>
-  } Kind = Normal;<br>
-<br>
-  // Default arguments of member function parameters that appear in a class<br>
-  // definition, as well as the initializers of data members, receive special<br>
-  // treatment. Identify them.<br>
-  if (ContextDecl) {<br>
-    if (ParmVarDecl *Param = dyn_cast<ParmVarDecl>(ContextDecl)) {<br>
-      if (const DeclContext *LexicalDC<br>
-          = Param->getDeclContext()->getLexicalParent())<br>
-        if (LexicalDC->isRecord())<br>
-          Kind = DefaultArgument;<br>
-    } else if (VarDecl *Var = dyn_cast<VarDecl>(ContextDecl)) {<br>
-      if (Var->getDeclContext()->isRecord())<br>
-        Kind = StaticDataMember;<br>
-    } else if (isa<FieldDecl>(ContextDecl)) {<br>
-      Kind = DataMember;<br>
-    }<br>
-  }<br>
-<br>
-  // Itanium ABI [5.1.7]:<br>
-  //   In the following contexts [...] the one-definition rule requires closure<br>
-  //   types in different translation units to "correspond":<br>
-  bool IsInNonspecializedTemplate =<br>
-    !ActiveTemplateInstantiations.empty() || CurContext->isDependentContext();<br>
-  unsigned ManglingNumber;<br>
-  switch (Kind) {<br>
-  case Normal:<br>
-    //  -- the bodies of non-exported nonspecialized template functions<br>
-    //  -- the bodies of inline functions<br>
-    if ((IsInNonspecializedTemplate &&<br>
-         !(ContextDecl && isa<ParmVarDecl>(ContextDecl))) ||<br>
-        isInInlineFunction(CurContext))<br>
-      ManglingNumber = Context.getLambdaManglingNumber(Method);<br>
-    else<br>
-      ManglingNumber = 0;<br>
-<br>
-    // There is no special context for this lambda.<br>
-    ContextDecl = 0;<br>
-    break;<br>
-<br>
-  case StaticDataMember:<br>
-    //  -- the initializers of nonspecialized static members of template classes<br>
-    if (!IsInNonspecializedTemplate) {<br>
-      ManglingNumber = 0;<br>
-      ContextDecl = 0;<br>
-      break;<br>
-    }<br>
-    // Fall through to assign a mangling number.<br>
-<br>
-  case DataMember:<br>
-    //  -- the in-class initializers of class members<br>
-  case DefaultArgument:<br>
-    //  -- default arguments appearing in class definitions<br>
-    ManglingNumber = ExprEvalContexts.back().getLambdaMangleContext()<br>
-                       .getManglingNumber(Method);<br>
-    break;<br>
+  Decl *ManglingContextDecl;<br>
+  if (MangleNumberingContext *MCtx =<br>
+          getCurrentMangleNumberContext(Class->getDeclContext(),<br>
+                                        ManglingContextDecl)) {<br>
+    unsigned ManglingNumber = MCtx->getManglingNumber(Method);<br>
+    Class->setLambdaMangling(ManglingNumber, ManglingContextDecl);<br>
   }<br>
<br>
-  Class->setLambdaMangling(ManglingNumber, ContextDecl);<br>
-<br>
   return Method;<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/<a href="http://blocks-irgen.mm" target="_blank">blocks-irgen.mm</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm?rev=185372&r1=185371&r2=185372&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm?rev=185372&r1=185371&r2=185372&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/<a href="http://blocks-irgen.mm" target="_blank">blocks-irgen.mm</a> (original)<br>
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/<a href="http://blocks-irgen.mm" target="_blank">blocks-irgen.mm</a> Mon Jul  1 15:22:57 2013<br>
@@ -14,7 +14,7 @@ namespace PR12746 {<br>
   }<br>
<br>
   // CHECK: define internal zeroext i1 @___ZN7PR127462f1EPi_block_invoke<br>
-  // CHECK: call zeroext i1 @"_ZNK23__block_prefix_internal3$_0clEv"<br>
+  // CHECK: call zeroext i1 @"_ZNK7PR127462f1Ub_3$_0clEv"<br>
<br>
   bool f2(int *x) {<br>
     auto outer = [&]() -> bool {<br>
<br>
Modified: cfe/trunk/test/CodeGenObjCXX/<a href="http://mangle-blocks.mm" target="_blank">mangle-blocks.mm</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/mangle-blocks.mm?rev=185372&r1=185371&r2=185372&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/mangle-blocks.mm?rev=185372&r1=185371&r2=185372&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/test/CodeGenObjCXX/<a href="http://mangle-blocks.mm" target="_blank">mangle-blocks.mm</a> (original)<br>
+++ cfe/trunk/test/CodeGenObjCXX/<a href="http://mangle-blocks.mm" target="_blank">mangle-blocks.mm</a> Mon Jul  1 15:22:57 2013<br>
@@ -1,13 +1,14 @@<br>
 // RUN: %clang_cc1 -emit-llvm -fblocks -o - -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 %s | FileCheck %s<br>
<br>
-// CHECK: @_ZGVN23__block_prefix_internal5valueE = internal global i64 0<br>
-// CHECK: @_ZN24__block_prefix_internal35namebE = internal global i8*<br>
+// CHECK: @_ZGVN3fooUb_5valueE = internal global i64 0<br>
+// CHECK: @_ZN26externally_visible_statics1SUb_1jE = linkonce_odr global i32 0<br>
+// CHECK: @_ZN26externally_visible_statics10inlinefuncUb_1iE = linkonce_odr global i32 0<br>
<br>
 int f();<br>
<br>
 void foo() {<br>
   // CHECK: define internal i32 @___Z3foov_block_invoke<br>
-  // CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVN23__block_prefix_internal5valueE<br>
+  // CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVN3fooUb_5valueE<br>
   (void)^(int x) {<br>
     static int value = f();<br>
     return x + value;<br>
@@ -25,7 +26,7 @@ int i = ^(int x) { return x;}(i);<br>
 - (void)method {<br>
   // CHECK: define internal signext i8 @"__11-[A method]_block_invoke"<br>
   (void)^(int x) {<br>
-    // CHECK: @_ZN24__block_prefix_internal04nameE<br>
+    // CHECK: @"_ZN11-[A method]Ub0_4nameE"<br>
     static const char *name = "hello";<br>
     return name[x];<br>
   };<br>
@@ -43,7 +44,7 @@ namespace N {<br>
   // CHECK: define internal signext i8 @___Z3fooi_block_invoke<br>
   void bar() {<br>
     (void)^(int x) {<br>
-      // CHECK: @_ZN24__block_prefix_internal14nameE<br>
+      // CHECK: @_ZN1N3barUb2_4nameE<br>
       static const char *name = "hello";<br>
       return name[x];<br>
     };<br>
@@ -55,8 +56,33 @@ class C {<br>
 };<br>
 C::C() {<br>
   (void)^(int x) {<br>
-    // CHECK: @_ZN24__block_prefix_internal35namebE<br>
+    // CHECK: @_ZN1CC1Ub3_5namebE<br>
     static const char *nameb = "hello";<br>
     return nameb[x];<br>
   };<br>
 }<br>
+<br>
+int f();<br>
+namespace externally_visible_statics {<br>
+  inline void inlinefunc() {<br>
+    ^{<br>
+      static int i = f();<br>
+    }();<br>
+  }<br>
+  struct S {<br>
+    int x = ^{<br>
+      static int j = f();<br>
+      return j;<br>
+    }();<br>
+    void foo(int y = ^{ static int k = f(); return k; }()) {}<br>
+  };<br>
+  void g() {<br>
+    inlinefunc();<br>
+    S s;<br>
+#if 0<br>
+    // FIXME: We know how to mangle k, but crash trying to mangle the<br>
+    // block itself.<br>
+    s.foo();<br>
+#endif<br>
+  }<br>
+}<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>