diff options
author | Mike Stump <mrs@apple.com> | 2009-02-21 20:00:35 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-02-21 20:00:35 +0000 |
commit | 4e7a1f7682d94811bd41fca8aefccc38f686db23 (patch) | |
tree | 781baa224e97254f4e097ab80c0175aca139a7a2 /lib/CodeGen/CGExprScalar.cpp | |
parent | 8dfb0c57ddb700b163afa89e3ab160f1de26753d (diff) |
Add CodeGen support for the helper for BlockDeclRefExprs. The easier
stuff is mostly done. Move BlockHasCopyDispose up.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65242 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprScalar.cpp')
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index eb13457372..63aa4e0a20 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -24,6 +24,7 @@ #include "llvm/Intrinsics.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/CFG.h" +#include "llvm/Target/TargetData.h" #include <cstdarg> using namespace clang; @@ -218,6 +219,8 @@ public: } Value *VisitStmtExpr(const StmtExpr *E); + + Value *VisitBlockDeclRefExpr(BlockDeclRefExpr *E); // Unary Operators. Value *VisitPrePostIncDec(const UnaryOperator *E, bool isInc, bool isPre); @@ -595,6 +598,48 @@ Value *ScalarExprEmitter::VisitStmtExpr(const StmtExpr *E) { !E->getType()->isVoidType()).getScalarVal(); } +Value *ScalarExprEmitter::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) { + if (E->isByRef()) { + // FIXME: Add codegen for __block variables. + return VisitExpr(E); + } + + // FIXME: We have most of the easy codegen for the helper, but we need to + // ensure we don't need copy/dispose, and we need to add the variables into + // the block literal still. + CGF.ErrorUnsupported(E, "scalar expression"); + + uint64_t &offset = CGF.BlockDecls[E->getDecl()]; + + const llvm::Type *Ty; + Ty = CGF.CGM.getTypes().ConvertType(E->getDecl()->getType()); + + // See if we have already allocated an offset for this variable. + if (offset == 0) { + int Size = CGF.CGM.getTargetData().getTypeStoreSizeInBits(Ty) / 8; + + unsigned Align = CGF.CGM.getContext().getTypeAlign(E->getDecl()->getType()); + if (const AlignedAttr* AA = E->getDecl()->getAttr<AlignedAttr>()) + Align = std::max(Align, AA->getAlignment()); + + // if not, allocate one now. + offset = CGF.getBlockOffset(Size, Align); + } + + llvm::Value *BlockLiteral = CGF.LoadBlockStruct(); + llvm::Value *V = Builder.CreateGEP(BlockLiteral, + llvm::ConstantInt::get(llvm::Type::Int64Ty, + offset), + "tmp"); + Ty = llvm::PointerType::get(Ty, 0); + if (E->isByRef()) + Ty = llvm::PointerType::get(Ty, 0); + V = Builder.CreateBitCast(V, Ty); + V = Builder.CreateLoad(V, false, "tmp"); + if (E->isByRef()) + V = Builder.CreateLoad(V, false, "tmp"); + return V; +} //===----------------------------------------------------------------------===// // Unary Operators |