r185372 - Fix mangling for block literals.
Nico Weber
thakis at chromium.org
Mon Jul 1 13:31:01 PDT 2013
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/682e5824/attachment.html>
More information about the cfe-commits
mailing list