r185372 - Fix mangling for block literals.

Eli Friedman eli.friedman at gmail.com
Mon Jul 1 13:36:58 PDT 2013


r185374.


On Mon, Jul 1, 2013 at 1:31 PM, Nico Weber <thakis at chromium.org> wrote:

> bb-chapuni: build #2569 of ninja-clang-i686-msc17-R is complete: Failure
> [failed build_clang]  Build details are at
> http://bb.pgr.jp/builders/ninja-clang-i686-msc17-R/builds/2569 blamelist: Eli Friedman <
> eli.friedman at gmail.com>
> g++:
> /home/bb/cmake-clang-x86_64-linux/llvm-project/clang/lib/AST/LambdaMangleContext.cpp:
> No such file or directory
> probably needs some cmake file update
>
>
>
> On Mon, Jul 1, 2013 at 1:22 PM, Eli Friedman <eli.friedman at gmail.com>wrote:
>
>> Author: efriedma
>> Date: Mon Jul  1 15:22:57 2013
>> New Revision: 185372
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=185372&view=rev
>> Log:
>> Fix mangling for block literals.
>>
>> Blocks, like lambdas, can be written in contexts which are required to be
>> treated as the same under ODR.  Unlike lambdas, it isn't possible to
>> actually
>> take the address of a block, so the mangling of the block itself doesn't
>> matter. However, objects like static variables inside a block do need to
>> be mangled in a consistent way.
>>
>> There are basically three components here. One, block literals need a
>> consistent numbering.  Two, objects/types inside a block literal need
>> to be mangled using it.  Three, objects/types inside a block literal need
>> to have their linkage computed correctly.
>>
>> Added:
>>     cfe/trunk/include/clang/AST/MangleNumberingContext.h
>>       - copied, changed from r185346,
>> cfe/trunk/include/clang/AST/LambdaMangleContext.h
>>     cfe/trunk/lib/AST/MangleNumberingContext.cpp
>>       - copied, changed from r185346,
>> cfe/trunk/lib/AST/LambdaMangleContext.cpp
>> Removed:
>>     cfe/trunk/include/clang/AST/LambdaMangleContext.h
>>     cfe/trunk/lib/AST/LambdaMangleContext.cpp
>> Modified:
>>     cfe/trunk/include/clang/AST/ASTContext.h
>>     cfe/trunk/include/clang/AST/Decl.h
>>     cfe/trunk/include/clang/Sema/Sema.h
>>     cfe/trunk/lib/AST/ASTContext.cpp
>>     cfe/trunk/lib/AST/Decl.cpp
>>     cfe/trunk/lib/AST/ItaniumMangle.cpp
>>     cfe/trunk/lib/CodeGen/CGDecl.cpp
>>     cfe/trunk/lib/CodeGen/CodeGenModule.cpp
>>     cfe/trunk/lib/CodeGen/CodeGenModule.h
>>     cfe/trunk/lib/Sema/SemaExpr.cpp
>>     cfe/trunk/lib/Sema/SemaLambda.cpp
>>     cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm
>>     cfe/trunk/test/CodeGenObjCXX/mangle-blocks.mm
>>
>> Modified: cfe/trunk/include/clang/AST/ASTContext.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=185372&r1=185371&r2=185372&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/AST/ASTContext.h (original)
>> +++ cfe/trunk/include/clang/AST/ASTContext.h Mon Jul  1 15:22:57 2013
>> @@ -19,7 +19,7 @@
>>  #include "clang/AST/CanonicalType.h"
>>  #include "clang/AST/CommentCommandTraits.h"
>>  #include "clang/AST/Decl.h"
>> -#include "clang/AST/LambdaMangleContext.h"
>> +#include "clang/AST/MangleNumberingContext.h"
>>  #include "clang/AST/NestedNameSpecifier.h"
>>  #include "clang/AST/PrettyPrinter.h"
>>  #include "clang/AST/RawCommentList.h"
>> @@ -338,9 +338,11 @@ class ASTContext : public RefCountedBase
>>    typedef llvm::TinyPtrVector<const CXXMethodDecl*> CXXMethodVector;
>>    llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>
>> OverriddenMethods;
>>
>> -  /// \brief Mapping from each declaration context to its corresponding
>> lambda
>> -  /// mangling context.
>> -  llvm::DenseMap<const DeclContext *, LambdaMangleContext>
>> LambdaMangleContexts;
>> +  /// \brief Mapping from each declaration context to its corresponding
>> +  /// mangling numbering context (used for constructs like lambdas which
>> +  /// need to be consistently numbered for the mangler).
>> +  llvm::DenseMap<const DeclContext *, MangleNumberingContext>
>> +      MangleNumberingContexts;
>>
>>    llvm::DenseMap<const DeclContext *, unsigned> UnnamedMangleContexts;
>>    llvm::DenseMap<const TagDecl *, unsigned> UnnamedMangleNumbers;
>> @@ -2087,9 +2089,10 @@ public:
>>    void addUnnamedTag(const TagDecl *Tag);
>>    int getUnnamedTagManglingNumber(const TagDecl *Tag) const;
>>
>> -  /// \brief Retrieve the lambda mangling number for a lambda expression.
>> -  unsigned getLambdaManglingNumber(CXXMethodDecl *CallOperator);
>> -
>> +  /// \brief Retrieve the context for computing mangling numbers in the
>> given
>> +  /// DeclContext.
>> +  MangleNumberingContext &getManglingNumberContext(DeclContext *DC);
>> +
>>    /// \brief Used by ParmVarDecl to store on the side the
>>    /// index of the parameter when it exceeds the size of the normal
>> bitfield.
>>    void setParameterIndex(const ParmVarDecl *D, unsigned index);
>>
>> Modified: cfe/trunk/include/clang/AST/Decl.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=185372&r1=185371&r2=185372&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/AST/Decl.h (original)
>> +++ cfe/trunk/include/clang/AST/Decl.h Mon Jul  1 15:22:57 2013
>> @@ -3115,13 +3115,17 @@ private:
>>    Capture *Captures;
>>    unsigned NumCaptures;
>>
>> +  unsigned ManglingNumber;
>> +  Decl *ManglingContextDecl;
>> +
>>  protected:
>>    BlockDecl(DeclContext *DC, SourceLocation CaretLoc)
>>      : Decl(Block, DC, CaretLoc), DeclContext(Block),
>>        IsVariadic(false), CapturesCXXThis(false),
>>        BlockMissingReturnType(true), IsConversionFromLambda(false),
>>        ParamInfo(0), NumParams(0), Body(0),
>> -      SignatureAsWritten(0), Captures(0), NumCaptures(0) {}
>> +      SignatureAsWritten(0), Captures(0), NumCaptures(0),
>> +      ManglingNumber(0), ManglingContextDecl(0) {}
>>
>>  public:
>>    static BlockDecl *Create(ASTContext &C, DeclContext *DC,
>> SourceLocation L);
>> @@ -3191,6 +3195,18 @@ public:
>>                     const Capture *end,
>>                     bool capturesCXXThis);
>>
>> +   unsigned getBlockManglingNumber() const {
>> +     return ManglingNumber;
>> +   }
>> +   Decl *getBlockManglingContextDecl() const {
>> +     return ManglingContextDecl;
>> +   }
>> +
>> +  void setBlockMangling(unsigned Number, Decl *Ctx) {
>> +    ManglingNumber = Number;
>> +    ManglingContextDecl = Ctx;
>> +  }
>> +
>>    virtual SourceRange getSourceRange() const LLVM_READONLY;
>>
>>    // Implement isa/cast/dyncast/etc.
>>
>> Removed: cfe/trunk/include/clang/AST/LambdaMangleContext.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/LambdaMangleContext.h?rev=185371&view=auto
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/AST/LambdaMangleContext.h (original)
>> +++ cfe/trunk/include/clang/AST/LambdaMangleContext.h (removed)
>> @@ -1,38 +0,0 @@
>> -//===--- LambdaMangleContext.h - 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 interface, which keeps
>> track of
>> -//  the Itanium C++ ABI mangling numbers for lambda expressions.
>> -//
>>
>> -//===----------------------------------------------------------------------===//
>> -#ifndef LLVM_CLANG_LAMBDAMANGLECONTEXT_H
>> -#define LLVM_CLANG_LAMBDAMANGLECONTEXT_H
>> -
>> -#include "clang/Basic/LLVM.h"
>> -#include "llvm/ADT/DenseMap.h"
>> -#include "llvm/ADT/IntrusiveRefCntPtr.h"
>> -
>> -namespace clang {
>> -
>> -class CXXMethodDecl;
>> -class FunctionProtoType;
>> -
>> -/// \brief Keeps track of the mangled names of lambda expressions within
>> a
>> -/// particular context.
>> -class LambdaMangleContext : public RefCountedBase<LambdaMangleContext> {
>> -  llvm::DenseMap<const FunctionProtoType *, unsigned> ManglingNumbers;
>> -
>> -public:
>> -  /// \brief Retrieve the mangling number of a new lambda expression
>> with the
>> -  /// given call operator within this lambda context.
>> -  unsigned getManglingNumber(CXXMethodDecl *CallOperator);
>> -};
>> -
>> -} // end namespace clang
>> -#endif
>>
>> Copied: cfe/trunk/include/clang/AST/MangleNumberingContext.h (from
>> r185346, cfe/trunk/include/clang/AST/LambdaMangleContext.h)
>> URL:
>> 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
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/AST/LambdaMangleContext.h (original)
>> +++ cfe/trunk/include/clang/AST/MangleNumberingContext.h Mon Jul  1
>> 15:22:57 2013
>> @@ -1,4 +1,4 @@
>> -//===--- LambdaMangleContext.h - Context for mangling lambdas ---*- C++
>> -*-===//
>> +//=== MangleNumberingContext.h - Context for mangling numbers ---*- C++
>> -*-===//
>>  //
>>  //                     The LLVM Compiler Infrastructure
>>  //
>> @@ -7,12 +7,13 @@
>>  //
>>
>>  //===----------------------------------------------------------------------===//
>>  //
>> -//  This file defines the LambdaMangleContext interface, which keeps
>> track of
>> -//  the Itanium C++ ABI mangling numbers for lambda expressions.
>> +//  This file defines the LambdaBlockMangleContext interface, which
>> keeps track
>> +//  of the Itanium C++ ABI mangling numbers for lambda expressions and
>> block
>> +//  literals.
>>  //
>>
>>  //===----------------------------------------------------------------------===//
>> -#ifndef LLVM_CLANG_LAMBDAMANGLECONTEXT_H
>> -#define LLVM_CLANG_LAMBDAMANGLECONTEXT_H
>> +#ifndef LLVM_CLANG_MANGLENUMBERINGCONTEXT_H
>> +#define LLVM_CLANG_MANGLENUMBERINGCONTEXT_H
>>
>>  #include "clang/Basic/LLVM.h"
>>  #include "llvm/ADT/DenseMap.h"
>> @@ -20,18 +21,24 @@
>>
>>  namespace clang {
>>
>> +class BlockDecl;
>>  class CXXMethodDecl;
>> -class FunctionProtoType;
>> +class Type;
>>
>> -/// \brief Keeps track of the mangled names of lambda expressions within
>> a
>> -/// particular context.
>> -class LambdaMangleContext : public RefCountedBase<LambdaMangleContext> {
>> -  llvm::DenseMap<const FunctionProtoType *, unsigned> ManglingNumbers;
>> +/// \brief Keeps track of the mangled names of lambda expressions and
>> block
>> +/// literals within a particular context.
>> +class MangleNumberingContext
>> +    : public RefCountedBase<MangleNumberingContext> {
>> +  llvm::DenseMap<const Type *, unsigned> ManglingNumbers;
>>
>>  public:
>>    /// \brief Retrieve the mangling number of a new lambda expression
>> with the
>> -  /// given call operator within this lambda context.
>> +  /// given call operator within this context.
>>    unsigned getManglingNumber(CXXMethodDecl *CallOperator);
>> +
>> +  /// \brief Retrieve the mangling number of a new block literal within
>> this
>> +  /// context.
>> +  unsigned getManglingNumber(BlockDecl *BD);
>>  };
>>
>>  } // end namespace clang
>>
>> Modified: cfe/trunk/include/clang/Sema/Sema.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=185372&r1=185371&r2=185372&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/Sema/Sema.h (original)
>> +++ cfe/trunk/include/clang/Sema/Sema.h Mon Jul  1 15:22:57 2013
>> @@ -20,7 +20,7 @@
>>  #include "clang/AST/Expr.h"
>>  #include "clang/AST/ExprObjC.h"
>>  #include "clang/AST/ExternalASTSource.h"
>> -#include "clang/AST/LambdaMangleContext.h"
>> +#include "clang/AST/MangleNumberingContext.h"
>>  #include "clang/AST/NSAPI.h"
>>  #include "clang/AST/PrettyPrinter.h"
>>  #include "clang/AST/TypeLoc.h"
>> @@ -662,17 +662,17 @@ public:
>>      /// is indeed an unevaluated context.
>>      SmallVector<LambdaExpr *, 2> Lambdas;
>>
>> -    /// \brief The declaration that provides context for the lambda
>> expression
>> -    /// if the normal declaration context does not suffice, e.g., in a
>> -    /// default function argument.
>> -    Decl *LambdaContextDecl;
>> +    /// \brief The declaration that provides context for lambda
>> expressions
>> +    /// and block literals if the normal declaration context does not
>> +    /// suffice, e.g., in a default function argument.
>> +    Decl *ManglingContextDecl;
>>
>>      /// \brief The context information used to mangle lambda expressions
>> -    /// within this context.
>> +    /// and block literals within this context.
>>      ///
>>      /// This mangling information is allocated lazily, since most
>> contexts
>> -    /// do not have lambda expressions.
>> -    IntrusiveRefCntPtr<LambdaMangleContext> LambdaMangle;
>> +    /// do not have lambda expressions or block literals.
>> +    IntrusiveRefCntPtr<MangleNumberingContext> MangleNumbering;
>>
>>      /// \brief If we are processing a decltype type, a set of call
>> expressions
>>      /// for which we have deferred checking the completeness of the
>> return type.
>> @@ -685,18 +685,19 @@ public:
>>      ExpressionEvaluationContextRecord(ExpressionEvaluationContext
>> Context,
>>                                        unsigned NumCleanupObjects,
>>                                        bool ParentNeedsCleanups,
>> -                                      Decl *LambdaContextDecl,
>> +                                      Decl *ManglingContextDecl,
>>                                        bool IsDecltype)
>>        : Context(Context), ParentNeedsCleanups(ParentNeedsCleanups),
>>          IsDecltype(IsDecltype), NumCleanupObjects(NumCleanupObjects),
>> -        LambdaContextDecl(LambdaContextDecl), LambdaMangle() { }
>> +        ManglingContextDecl(ManglingContextDecl), MangleNumbering() { }
>>
>> -    /// \brief Retrieve the mangling context for lambdas.
>> -    LambdaMangleContext &getLambdaMangleContext() {
>> -      assert(LambdaContextDecl && "Need to have a lambda context
>> declaration");
>> -      if (!LambdaMangle)
>> -        LambdaMangle = new LambdaMangleContext;
>> -      return *LambdaMangle;
>> +    /// \brief Retrieve the mangling numbering context, used to
>> consistently
>> +    /// number constructs like lambdas for mangling.
>> +    MangleNumberingContext &getMangleNumberingContext() {
>> +      assert(ManglingContextDecl && "Need to have a context
>> declaration");
>> +      if (!MangleNumbering)
>> +        MangleNumbering = new MangleNumberingContext;
>> +      return *MangleNumbering;
>>      }
>>
>>      bool isUnevaluated() const {
>> @@ -707,6 +708,18 @@ public:
>>    /// A stack of expression evaluation contexts.
>>    SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts;
>>
>> +  /// \brief Compute the mangling number context for a lambda expression
>> or
>> +  /// block literal.
>> +  ///
>> +  /// \param DC - The DeclContext containing the lambda expression or
>> +  /// block literal.
>> +  /// \param[out] ManglingContextDecl - Returns the ManglingContextDecl
>> +  /// associated with the context, if relevant.
>> +  MangleNumberingContext *getCurrentMangleNumberContext(
>> +    DeclContext *DC,
>> +    Decl *&ManglingContextDecl);
>> +
>> +
>>    /// SpecialMemberOverloadResult - The overloading result for a special
>> member
>>    /// function.
>>    ///
>>
>> Modified: cfe/trunk/lib/AST/ASTContext.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=185372&r1=185371&r2=185372&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/AST/ASTContext.cpp (original)
>> +++ cfe/trunk/lib/AST/ASTContext.cpp Mon Jul  1 15:22:57 2013
>> @@ -8007,13 +8007,10 @@ int ASTContext::getUnnamedTagManglingNum
>>    return I != UnnamedMangleNumbers.end() ? I->second : -1;
>>  }
>>
>> -unsigned ASTContext::getLambdaManglingNumber(CXXMethodDecl
>> *CallOperator) {
>> -  CXXRecordDecl *Lambda = CallOperator->getParent();
>> -  return LambdaMangleContexts[Lambda->getDeclContext()]
>> -           .getManglingNumber(CallOperator);
>> +MangleNumberingContext &ASTContext::getManglingNumberContext(DeclContext
>> *DC) {
>> +  return MangleNumberingContexts[DC];
>>  }
>>
>> -
>>  void ASTContext::setParameterIndex(const ParmVarDecl *D, unsigned int
>> index) {
>>    ParamIndices[D] = index;
>>  }
>>
>> Modified: cfe/trunk/lib/AST/Decl.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=185372&r1=185371&r2=185372&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/AST/Decl.cpp (original)
>> +++ cfe/trunk/lib/AST/Decl.cpp Mon Jul  1 15:22:57 2013
>> @@ -287,13 +287,12 @@ getLVForTemplateParameterList(const Temp
>>  static LinkageInfo getLVForDecl(const NamedDecl *D,
>>                                  LVComputationKind computation);
>>
>> -static const FunctionDecl *getOutermostFunctionContext(const Decl *D) {
>> -  const FunctionDecl *Ret = NULL;
>> +static const Decl *getOutermostFuncOrBlockContext(const Decl *D) {
>> +  const Decl *Ret = NULL;
>>    const DeclContext *DC = D->getDeclContext();
>>    while (DC->getDeclKind() != Decl::TranslationUnit) {
>> -    const FunctionDecl *F = dyn_cast<FunctionDecl>(DC);
>> -    if (F)
>> -      Ret = F;
>> +    if (isa<FunctionDecl>(DC) || isa<BlockDecl>(DC))
>> +      Ret = cast<Decl>(DC);
>>      DC = DC->getParent();
>>    }
>>    return Ret;
>> @@ -996,6 +995,22 @@ NamedDecl::getExplicitVisibility(Explici
>>    return None;
>>  }
>>
>> +static LinkageInfo getLVForClosure(const DeclContext *DC, Decl
>> *ContextDecl,
>> +                                   LVComputationKind computation) {
>> +  // This lambda has its linkage/visibility determined by its owner.
>> +  if (ContextDecl) {
>> +    if (isa<ParmVarDecl>(ContextDecl))
>> +      DC = ContextDecl->getDeclContext()->getRedeclContext();
>> +    else
>> +      return getLVForDecl(cast<NamedDecl>(ContextDecl), computation);
>> +  }
>> +
>> +  if (const NamedDecl *ND = dyn_cast<NamedDecl>(DC))
>> +    return getLVForDecl(ND, computation);
>> +
>> +  return LinkageInfo::external();
>> +}
>> +
>>  static LinkageInfo getLVForLocalDecl(const NamedDecl *D,
>>                                       LVComputationKind computation) {
>>    if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
>> @@ -1052,14 +1067,25 @@ static LinkageInfo getLVForLocalDecl(con
>>    if (!Context.getLangOpts().CPlusPlus)
>>      return LinkageInfo::none();
>>
>> -  const FunctionDecl *FD = getOutermostFunctionContext(D);
>> -  if (!FD)
>> +  const Decl *OuterD = getOutermostFuncOrBlockContext(D);
>> +  if (!OuterD)
>>      return LinkageInfo::none();
>>
>> -  if (!FD->isInlined() && FD->getTemplateSpecializationKind() ==
>> TSK_Undeclared)
>> -    return LinkageInfo::none();
>> +  LinkageInfo LV;
>> +  if (const BlockDecl *BD = dyn_cast<BlockDecl>(OuterD)) {
>> +    if (!BD->getBlockManglingNumber())
>> +      return LinkageInfo::none();
>> +
>> +    LV = getLVForClosure(BD->getDeclContext()->getRedeclContext(),
>> +                         BD->getBlockManglingContextDecl(), computation);
>> +  } else {
>> +    const FunctionDecl *FD = cast<FunctionDecl>(OuterD);
>> +    if (!FD->isInlined() &&
>> +        FD->getTemplateSpecializationKind() == TSK_Undeclared)
>> +      return LinkageInfo::none();
>>
>> -  LinkageInfo LV = getLVForDecl(FD, computation);
>> +    LV = getLVForDecl(FD, computation);
>> +  }
>>    if (!isExternallyVisible(LV.getLinkage()))
>>      return LinkageInfo::none();
>>    return LinkageInfo(VisibleNoLinkage, LV.getVisibility(),
>> @@ -1095,20 +1121,10 @@ static LinkageInfo computeLVForDecl(cons
>>            // 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),
>> computation);
>> -        }
>>
>> -        if (const NamedDecl *ND = dyn_cast<NamedDecl>(DC))
>> -          return getLVForDecl(ND, computation);
>> -
>> -        return LinkageInfo::external();
>> +        // This lambda has its linkage/visibility determined by its
>> owner.
>> +        return getLVForClosure(D->getDeclContext()->getRedeclContext(),
>> +                               Record->getLambdaContextDecl(),
>> computation);
>>        }
>>
>>        break;
>>
>> Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=185372&r1=185371&r2=185372&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
>> +++ cfe/trunk/lib/AST/ItaniumMangle.cpp Mon Jul  1 15:22:57 2013
>> @@ -1416,15 +1416,22 @@ void CXXNameMangler::manglePrefix(const
>>      return;
>>
>>    if (const BlockDecl *Block = dyn_cast<BlockDecl>(DC)) {
>> -    // The symbol we're adding a prefix for isn't externally
>> -    // visible; make up something sane.
>> -    // FIXME: This isn't always true!
>> -    SmallString<16> BlockPrefix;
>> -    BlockPrefix += "__block_prefix_internal";
>> -    unsigned Number = Context.getBlockId(Block, false);
>> +    // Reflect the lambda mangling rules, except that we don't have an
>> +    // actual function declaration.
>> +    if (NoFunction)
>> +      return;
>> +
>> +    manglePrefix(getEffectiveParentContext(DC), NoFunction);
>> +    // If we have a block mangling number, use it.
>> +    unsigned Number = Block->getBlockManglingNumber();
>> +    // Otherwise, just make up a number. It doesn't matter what it is
>> because
>> +    // the symbol in question isn't externally visible.
>> +    if (!Number)
>> +      Number = Context.getBlockId(Block, false);
>> +    Out << "Ub";
>>      if (Number > 1)
>> -      BlockPrefix += llvm::utostr_32(Number - 2);
>> -    Out << BlockPrefix.size() << BlockPrefix;
>> +      Out << Number - 2;
>> +    Out << '_';
>>      return;
>>    } else if (isa<CapturedDecl>(DC)) {
>>      // Skip CapturedDecl context.
>>
>> Removed: cfe/trunk/lib/AST/LambdaMangleContext.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/LambdaMangleContext.cpp?rev=185371&view=auto
>>
>> ==============================================================================
>> --- cfe/trunk/lib/AST/LambdaMangleContext.cpp (original)
>> +++ cfe/trunk/lib/AST/LambdaMangleContext.cpp (removed)
>> @@ -1,30 +0,0 @@
>> -//===--- 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/ASTContext.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->getArgTypes(),
>> -
>> FunctionProtoType::ExtProtoInfo());
>> -  Key = Context.getCanonicalType(Key);
>> -  return ++ManglingNumbers[Key->castAs<FunctionProtoType>()];
>> -}
>>
>> Copied: cfe/trunk/lib/AST/MangleNumberingContext.cpp (from r185346,
>> cfe/trunk/lib/AST/LambdaMangleContext.cpp)
>> URL:
>> 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
>>
>> ==============================================================================
>> --- cfe/trunk/lib/AST/LambdaMangleContext.cpp (original)
>> +++ cfe/trunk/lib/AST/MangleNumberingContext.cpp Mon Jul  1 15:22:57 2013
>> @@ -1,4 +1,4 @@
>> -//===--- LambdaMangleContext.cpp - Context for mangling lambdas -*- C++
>> -*-===//
>> +//===--- MangleNumberingContext.cpp - Context for mangling numbers
>> --------===//
>>  //
>>  //                     The LLVM Compiler Infrastructure
>>  //
>> @@ -12,13 +12,14 @@
>>  //
>>
>>  //===----------------------------------------------------------------------===//
>>
>> -#include "clang/AST/LambdaMangleContext.h"
>> +#include "clang/AST/MangleNumberingContext.h"
>>  #include "clang/AST/ASTContext.h"
>>  #include "clang/AST/DeclCXX.h"
>>
>>  using namespace clang;
>>
>> -unsigned LambdaMangleContext::getManglingNumber(CXXMethodDecl
>> *CallOperator) {
>> +unsigned
>> +MangleNumberingContext::getManglingNumber(CXXMethodDecl *CallOperator) {
>>    const FunctionProtoType *Proto
>>      = CallOperator->getType()->getAs<FunctionProtoType>();
>>    ASTContext &Context = CallOperator->getASTContext();
>> @@ -28,3 +29,10 @@ unsigned LambdaMangleContext::getManglin
>>    Key = Context.getCanonicalType(Key);
>>    return ++ManglingNumbers[Key->castAs<FunctionProtoType>()];
>>  }
>> +
>> +unsigned
>> +MangleNumberingContext::getManglingNumber(BlockDecl *BD) {
>> +  // FIXME: Compute a BlockPointerType?  Not obvious how.
>> +  const Type *Ty = 0;
>> +  return ++ManglingNumbers[Ty];
>> +}
>>
>> Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=185372&r1=185371&r2=185372&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
>> +++ cfe/trunk/lib/CodeGen/CGDecl.cpp Mon Jul  1 15:22:57 2013
>> @@ -130,9 +130,27 @@ void CodeGenFunction::EmitVarDecl(const
>>      if (D.isExternallyVisible()) {
>>        const Decl *D = CurCodeDecl;
>>        while (true) {
>> -        if (isa<BlockDecl>(D)) {
>> -          // FIXME: Handle this case properly!  (Should be similar to the
>> -          // way we handle lambdas in computeLVForDecl in Decl.cpp.)
>> +        if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
>> +          if (!BD->getBlockManglingNumber())
>> +            break;
>> +
>> +          // This block has the linkage/visibility of its contained
>> variables
>> +          // determined by its owner.
>> +          const DeclContext *DC =
>> D->getDeclContext()->getRedeclContext();
>> +          if (Decl *ContextDecl = BD->getBlockManglingContextDecl()) {
>> +            if (isa<ParmVarDecl>(ContextDecl)) {
>> +              DC = ContextDecl->getDeclContext()->getRedeclContext();
>> +            } else {
>> +              D = ContextDecl;
>> +              continue;
>> +            }
>> +          }
>> +
>> +          if (const NamedDecl *ND = dyn_cast<NamedDecl>(DC)) {
>> +            D = ND;
>> +            continue;
>> +          }
>> +
>>            break;
>>          } else if (isa<CapturedDecl>(D)) {
>>            D = cast<Decl>(cast<CapturedDecl>(D)->getParent());
>> @@ -140,13 +158,26 @@ void CodeGenFunction::EmitVarDecl(const
>>            break;
>>          }
>>        }
>> -      // FIXME: Do we really only care about FunctionDecls here?
>> +      llvm::GlobalValue::LinkageTypes ParentLinkage;
>>        if (isa<FunctionDecl>(D)) {
>> -        llvm::GlobalValue::LinkageTypes ParentLinkage =
>> -            CGM.getFunctionLinkage(cast<FunctionDecl>(D));
>> -        if (llvm::GlobalValue::isWeakForLinker(ParentLinkage))
>> -          Linkage = ParentLinkage;
>> +        ParentLinkage = CGM.getFunctionLinkage(cast<FunctionDecl>(D));
>> +      } else if (isa<VarDecl>(D)) {
>> +        // FIXME: I'm pretty sure this is wrong...
>> +        ParentLinkage = CGM.GetLLVMLinkageVarDefinition(cast<VarDecl>(D),
>> +
>>  /*constant*/false);
>> +      } else {
>> +        assert(isa<FieldDecl>(D) && "Expect function, variable, or
>> field");
>> +        // FIXME: Is this right?
>> +        ParentLinkage = llvm::GlobalValue::LinkOnceODRLinkage;
>>        }
>> +
>> +      if (llvm::GlobalValue::isWeakForLinker(ParentLinkage))
>> +        Linkage = ParentLinkage;
>> +
>> +      // FIXME: We need to force the emission/use of a guard variable for
>> +      // some variables even if we can constant-evaluate them because
>> +      // we can't guarantee every translation unit will
>> constant-evaluate them.
>> +      // Also, we might need to fix up the linkage.
>>      }
>>
>>      return EmitStaticVarDecl(D, Linkage);
>>
>> Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=185372&r1=185371&r2=185372&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
>> +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Mon Jul  1 15:22:57 2013
>> @@ -1797,7 +1797,7 @@ void CodeGenModule::EmitGlobalVarDefinit
>>
>>    // Set the llvm linkage type as appropriate.
>>    llvm::GlobalValue::LinkageTypes Linkage =
>> -    GetLLVMLinkageVarDefinition(D, GV);
>> +    GetLLVMLinkageVarDefinition(D, GV->isConstant());
>>    GV->setLinkage(Linkage);
>>    if (Linkage == llvm::GlobalVariable::CommonLinkage)
>>      // common vars aren't constant even if declared const.
>> @@ -1828,8 +1828,7 @@ void CodeGenModule::EmitGlobalVarDefinit
>>  }
>>
>>  llvm::GlobalValue::LinkageTypes
>> -CodeGenModule::GetLLVMLinkageVarDefinition(const VarDecl *D,
>> -                                           llvm::GlobalVariable *GV) {
>> +CodeGenModule::GetLLVMLinkageVarDefinition(const VarDecl *D, bool
>> isConstant) {
>>    GVALinkage Linkage = getContext().GetGVALinkageForVariable(D);
>>    if (Linkage == GVA_Internal)
>>      return llvm::Function::InternalLinkage;
>> @@ -1844,7 +1843,7 @@ CodeGenModule::GetLLVMLinkageVarDefiniti
>>      // http://msdn.microsoft.com/en-us/library/5tkz6s71.aspx
>>      return llvm::GlobalVariable::WeakODRLinkage;
>>    } else if (D->hasAttr<WeakAttr>()) {
>> -    if (GV->isConstant())
>> +    if (isConstant)
>>        return llvm::GlobalVariable::WeakODRLinkage;
>>      else
>>        return llvm::GlobalVariable::WeakAnyLinkage;
>>
>> Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=185372&r1=185371&r2=185372&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
>> +++ cfe/trunk/lib/CodeGen/CodeGenModule.h Mon Jul  1 15:22:57 2013
>> @@ -942,8 +942,7 @@ public:
>>    /// GetLLVMLinkageVarDefinition - Returns LLVM linkage for a global
>>    /// variable.
>>    llvm::GlobalValue::LinkageTypes
>> -  GetLLVMLinkageVarDefinition(const VarDecl *D,
>> -                              llvm::GlobalVariable *GV);
>> +  GetLLVMLinkageVarDefinition(const VarDecl *D, bool isConstant);
>>
>>    /// Emit all the global annotations.
>>    void EmitGlobalAnnotations();
>>
>> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=185372&r1=185371&r2=185372&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jul  1 15:22:57 2013
>> @@ -9810,6 +9810,17 @@ ExprResult Sema::ActOnChooseExpr(SourceL
>>  /// ActOnBlockStart - This callback is invoked when a block literal is
>> started.
>>  void Sema::ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope) {
>>    BlockDecl *Block = BlockDecl::Create(Context, CurContext, CaretLoc);
>> +
>> +  {
>> +    Decl *ManglingContextDecl;
>> +    if (MangleNumberingContext *MCtx =
>> +            getCurrentMangleNumberContext(Block->getDeclContext(),
>> +                                          ManglingContextDecl)) {
>> +      unsigned ManglingNumber = MCtx->getManglingNumber(Block);
>> +      Block->setBlockMangling(ManglingNumber, ManglingContextDecl);
>> +    }
>> +  }
>> +
>>    PushBlockScope(CurScope, Block);
>>    CurContext->addDecl(Block);
>>    if (CurScope)
>> @@ -9929,11 +9940,7 @@ void Sema::ActOnBlockArguments(SourceLoc
>>    // Finally we can process decl attributes.
>>    ProcessDeclAttributes(CurScope, CurBlock->TheDecl, ParamInfo);
>>
>> -  // Put the parameter variables in scope.  We can bail out immediately
>> -  // if we don't have any.
>> -  if (Params.empty())
>> -    return;
>> -
>> +  // Put the parameter variables in scope.
>>    for (BlockDecl::param_iterator AI = CurBlock->TheDecl->param_begin(),
>>           E = CurBlock->TheDecl->param_end(); AI != E; ++AI) {
>>      (*AI)->setOwningFunction(CurBlock->TheDecl);
>> @@ -10641,8 +10648,8 @@ void
>>  Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext
>> NewContext,
>>                                        ReuseLambdaContextDecl_t,
>>                                        bool IsDecltype) {
>> -  Decl *LambdaContextDecl = ExprEvalContexts.back().LambdaContextDecl;
>> -  PushExpressionEvaluationContext(NewContext, LambdaContextDecl,
>> IsDecltype);
>> +  Decl *ClosureContextDecl = ExprEvalContexts.back().ManglingContextDecl;
>> +  PushExpressionEvaluationContext(NewContext, ClosureContextDecl,
>> IsDecltype);
>>  }
>>
>>  void Sema::PopExpressionEvaluationContext() {
>>
>> Modified: cfe/trunk/lib/Sema/SemaLambda.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=185372&r1=185371&r2=185372&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaLambda.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaLambda.cpp Mon Jul  1 15:22:57 2013
>> @@ -52,6 +52,72 @@ static bool isInInlineFunction(const Dec
>>    return false;
>>  }
>>
>> +MangleNumberingContext *
>> +Sema::getCurrentMangleNumberContext(DeclContext *DC,
>> +                                    Decl *&ManglingContextDecl) {
>> +  // Compute the context for allocating mangling numbers in the current
>> +  // expression, if the ABI requires them.
>> +  ManglingContextDecl = ExprEvalContexts.back().ManglingContextDecl;
>> +
>> +  enum ContextKind {
>> +    Normal,
>> +    DefaultArgument,
>> +    DataMember,
>> +    StaticDataMember
>> +  } Kind = Normal;
>> +
>> +  // Default arguments of member function parameters that appear in a
>> class
>> +  // definition, as well as the initializers of data members, receive
>> special
>> +  // treatment. Identify them.
>> +  if (ManglingContextDecl) {
>> +    if (ParmVarDecl *Param = dyn_cast<ParmVarDecl>(ManglingContextDecl))
>> {
>> +      if (const DeclContext *LexicalDC
>> +          = Param->getDeclContext()->getLexicalParent())
>> +        if (LexicalDC->isRecord())
>> +          Kind = DefaultArgument;
>> +    } else if (VarDecl *Var = dyn_cast<VarDecl>(ManglingContextDecl)) {
>> +      if (Var->getDeclContext()->isRecord())
>> +        Kind = StaticDataMember;
>> +    } else if (isa<FieldDecl>(ManglingContextDecl)) {
>> +      Kind = DataMember;
>> +    }
>> +  }
>> +
>> +  // Itanium ABI [5.1.7]:
>> +  //   In the following contexts [...] the one-definition rule requires
>> closure
>> +  //   types in different translation units to "correspond":
>> +  bool IsInNonspecializedTemplate =
>> +    !ActiveTemplateInstantiations.empty() ||
>> CurContext->isDependentContext();
>> +  switch (Kind) {
>> +  case Normal:
>> +    //  -- the bodies of non-exported nonspecialized template functions
>> +    //  -- the bodies of inline functions
>> +    if ((IsInNonspecializedTemplate &&
>> +         !(ManglingContextDecl &&
>> isa<ParmVarDecl>(ManglingContextDecl))) ||
>> +        isInInlineFunction(CurContext)) {
>> +      ManglingContextDecl = 0;
>> +      return &Context.getManglingNumberContext(DC);
>> +    }
>> +
>> +    ManglingContextDecl = 0;
>> +    return 0;
>> +
>> +  case StaticDataMember:
>> +    //  -- the initializers of nonspecialized static members of template
>> classes
>> +    if (!IsInNonspecializedTemplate) {
>> +      ManglingContextDecl = 0;
>> +      return 0;
>> +    }
>> +    // Fall through to get the current context.
>> +
>> +  case DataMember:
>> +    //  -- the in-class initializers of class members
>> +  case DefaultArgument:
>> +    //  -- default arguments appearing in class definitions
>> +    return &ExprEvalContexts.back().getMangleNumberingContext();
>> +  }
>> +}
>> +
>>  CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class,
>>                   SourceRange IntroducerRange,
>>                   TypeSourceInfo *MethodType,
>> @@ -98,75 +164,14 @@ CXXMethodDecl *Sema::startLambdaDefiniti
>>        (*P)->setOwningFunction(Method);
>>    }
>>
>> -  // Allocate a mangling number for this lambda expression, if the ABI
>> -  // requires one.
>> -  Decl *ContextDecl = ExprEvalContexts.back().LambdaContextDecl;
>> -
>> -  enum ContextKind {
>> -    Normal,
>> -    DefaultArgument,
>> -    DataMember,
>> -    StaticDataMember
>> -  } Kind = Normal;
>> -
>> -  // Default arguments of member function parameters that appear in a
>> class
>> -  // definition, as well as the initializers of data members, receive
>> special
>> -  // treatment. Identify them.
>> -  if (ContextDecl) {
>> -    if (ParmVarDecl *Param = dyn_cast<ParmVarDecl>(ContextDecl)) {
>> -      if (const DeclContext *LexicalDC
>> -          = Param->getDeclContext()->getLexicalParent())
>> -        if (LexicalDC->isRecord())
>> -          Kind = DefaultArgument;
>> -    } else if (VarDecl *Var = dyn_cast<VarDecl>(ContextDecl)) {
>> -      if (Var->getDeclContext()->isRecord())
>> -        Kind = StaticDataMember;
>> -    } else if (isa<FieldDecl>(ContextDecl)) {
>> -      Kind = DataMember;
>> -    }
>> -  }
>> -
>> -  // Itanium ABI [5.1.7]:
>> -  //   In the following contexts [...] the one-definition rule requires
>> closure
>> -  //   types in different translation units to "correspond":
>> -  bool IsInNonspecializedTemplate =
>> -    !ActiveTemplateInstantiations.empty() ||
>> CurContext->isDependentContext();
>> -  unsigned ManglingNumber;
>> -  switch (Kind) {
>> -  case Normal:
>> -    //  -- the bodies of non-exported nonspecialized template functions
>> -    //  -- the bodies of inline functions
>> -    if ((IsInNonspecializedTemplate &&
>> -         !(ContextDecl && isa<ParmVarDecl>(ContextDecl))) ||
>> -        isInInlineFunction(CurContext))
>> -      ManglingNumber = Context.getLambdaManglingNumber(Method);
>> -    else
>> -      ManglingNumber = 0;
>> -
>> -    // There is no special context for this lambda.
>> -    ContextDecl = 0;
>> -    break;
>> -
>> -  case StaticDataMember:
>> -    //  -- the initializers of nonspecialized static members of template
>> classes
>> -    if (!IsInNonspecializedTemplate) {
>> -      ManglingNumber = 0;
>> -      ContextDecl = 0;
>> -      break;
>> -    }
>> -    // Fall through to assign a mangling number.
>> -
>> -  case DataMember:
>> -    //  -- the in-class initializers of class members
>> -  case DefaultArgument:
>> -    //  -- default arguments appearing in class definitions
>> -    ManglingNumber = ExprEvalContexts.back().getLambdaMangleContext()
>> -                       .getManglingNumber(Method);
>> -    break;
>> +  Decl *ManglingContextDecl;
>> +  if (MangleNumberingContext *MCtx =
>> +          getCurrentMangleNumberContext(Class->getDeclContext(),
>> +                                        ManglingContextDecl)) {
>> +    unsigned ManglingNumber = MCtx->getManglingNumber(Method);
>> +    Class->setLambdaMangling(ManglingNumber, ManglingContextDecl);
>>    }
>>
>> -  Class->setLambdaMangling(ManglingNumber, ContextDecl);
>> -
>>    return Method;
>>  }
>>
>>
>> Modified: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/
>> blocks-irgen.mm
>> URL:
>> 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
>>
>> ==============================================================================
>> --- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm(original)
>> +++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mmMon Jul  1 15:22:57 2013
>> @@ -14,7 +14,7 @@ namespace PR12746 {
>>    }
>>
>>    // CHECK: define internal zeroext i1 @___ZN7PR127462f1EPi_block_invoke
>> -  // CHECK: call zeroext i1 @"_ZNK23__block_prefix_internal3$_0clEv"
>> +  // CHECK: call zeroext i1 @"_ZNK7PR127462f1Ub_3$_0clEv"
>>
>>    bool f2(int *x) {
>>      auto outer = [&]() -> bool {
>>
>> Modified: cfe/trunk/test/CodeGenObjCXX/mangle-blocks.mm
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/mangle-blocks.mm?rev=185372&r1=185371&r2=185372&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/CodeGenObjCXX/mangle-blocks.mm (original)
>> +++ cfe/trunk/test/CodeGenObjCXX/mangle-blocks.mm Mon Jul  1 15:22:57
>> 2013
>> @@ -1,13 +1,14 @@
>>  // RUN: %clang_cc1 -emit-llvm -fblocks -o - -triple
>> x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 %s | FileCheck %s
>>
>> -// CHECK: @_ZGVN23__block_prefix_internal5valueE = internal global i64 0
>> -// CHECK: @_ZN24__block_prefix_internal35namebE = internal global i8*
>> +// CHECK: @_ZGVN3fooUb_5valueE = internal global i64 0
>> +// CHECK: @_ZN26externally_visible_statics1SUb_1jE = linkonce_odr global
>> i32 0
>> +// CHECK: @_ZN26externally_visible_statics10inlinefuncUb_1iE =
>> linkonce_odr global i32 0
>>
>>  int f();
>>
>>  void foo() {
>>    // CHECK: define internal i32 @___Z3foov_block_invoke
>> -  // CHECK: call i32 @__cxa_guard_acquire(i64*
>> @_ZGVN23__block_prefix_internal5valueE
>> +  // CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVN3fooUb_5valueE
>>    (void)^(int x) {
>>      static int value = f();
>>      return x + value;
>> @@ -25,7 +26,7 @@ int i = ^(int x) { return x;}(i);
>>  - (void)method {
>>    // CHECK: define internal signext i8 @"__11-[A method]_block_invoke"
>>    (void)^(int x) {
>> -    // CHECK: @_ZN24__block_prefix_internal04nameE
>> +    // CHECK: @"_ZN11-[A method]Ub0_4nameE"
>>      static const char *name = "hello";
>>      return name[x];
>>    };
>> @@ -43,7 +44,7 @@ namespace N {
>>    // CHECK: define internal signext i8 @___Z3fooi_block_invoke
>>    void bar() {
>>      (void)^(int x) {
>> -      // CHECK: @_ZN24__block_prefix_internal14nameE
>> +      // CHECK: @_ZN1N3barUb2_4nameE
>>        static const char *name = "hello";
>>        return name[x];
>>      };
>> @@ -55,8 +56,33 @@ class C {
>>  };
>>  C::C() {
>>    (void)^(int x) {
>> -    // CHECK: @_ZN24__block_prefix_internal35namebE
>> +    // CHECK: @_ZN1CC1Ub3_5namebE
>>      static const char *nameb = "hello";
>>      return nameb[x];
>>    };
>>  }
>> +
>> +int f();
>> +namespace externally_visible_statics {
>> +  inline void inlinefunc() {
>> +    ^{
>> +      static int i = f();
>> +    }();
>> +  }
>> +  struct S {
>> +    int x = ^{
>> +      static int j = f();
>> +      return j;
>> +    }();
>> +    void foo(int y = ^{ static int k = f(); return k; }()) {}
>> +  };
>> +  void g() {
>> +    inlinefunc();
>> +    S s;
>> +#if 0
>> +    // FIXME: We know how to mangle k, but crash trying to mangle the
>> +    // block itself.
>> +    s.foo();
>> +#endif
>> +  }
>> +}
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130701/6cd82682/attachment.html>


More information about the cfe-commits mailing list