1f4a2713aSLionel Sambuc //===-- CGBlocks.h - state for LLVM CodeGen for blocks ----------*- C++ -*-===// 2f4a2713aSLionel Sambuc // 3f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure 4f4a2713aSLionel Sambuc // 5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source 6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details. 7f4a2713aSLionel Sambuc // 8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 9f4a2713aSLionel Sambuc // 10f4a2713aSLionel Sambuc // This is the internal state used for llvm translation for block literals. 11f4a2713aSLionel Sambuc // 12f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 13f4a2713aSLionel Sambuc 14*0a6a1f1dSLionel Sambuc #ifndef LLVM_CLANG_LIB_CODEGEN_CGBLOCKS_H 15*0a6a1f1dSLionel Sambuc #define LLVM_CLANG_LIB_CODEGEN_CGBLOCKS_H 16f4a2713aSLionel Sambuc 17f4a2713aSLionel Sambuc #include "CGBuilder.h" 18f4a2713aSLionel Sambuc #include "CGCall.h" 19f4a2713aSLionel Sambuc #include "CGValue.h" 20f4a2713aSLionel Sambuc #include "CodeGenFunction.h" 21f4a2713aSLionel Sambuc #include "CodeGenTypes.h" 22f4a2713aSLionel Sambuc #include "clang/AST/CharUnits.h" 23f4a2713aSLionel Sambuc #include "clang/AST/Expr.h" 24f4a2713aSLionel Sambuc #include "clang/AST/ExprCXX.h" 25f4a2713aSLionel Sambuc #include "clang/AST/ExprObjC.h" 26f4a2713aSLionel Sambuc #include "clang/AST/Type.h" 27f4a2713aSLionel Sambuc #include "clang/Basic/TargetInfo.h" 28f4a2713aSLionel Sambuc #include "llvm/IR/Module.h" 29f4a2713aSLionel Sambuc 30f4a2713aSLionel Sambuc namespace llvm { 31f4a2713aSLionel Sambuc class Module; 32f4a2713aSLionel Sambuc class Constant; 33f4a2713aSLionel Sambuc class Function; 34f4a2713aSLionel Sambuc class GlobalValue; 35f4a2713aSLionel Sambuc class DataLayout; 36f4a2713aSLionel Sambuc class FunctionType; 37f4a2713aSLionel Sambuc class PointerType; 38f4a2713aSLionel Sambuc class Value; 39f4a2713aSLionel Sambuc class LLVMContext; 40f4a2713aSLionel Sambuc } 41f4a2713aSLionel Sambuc 42f4a2713aSLionel Sambuc namespace clang { 43f4a2713aSLionel Sambuc 44f4a2713aSLionel Sambuc namespace CodeGen { 45f4a2713aSLionel Sambuc 46f4a2713aSLionel Sambuc class CodeGenModule; 47f4a2713aSLionel Sambuc class CGBlockInfo; 48f4a2713aSLionel Sambuc 49f4a2713aSLionel Sambuc // Flags stored in __block variables. 50f4a2713aSLionel Sambuc enum BlockByrefFlags { 51f4a2713aSLionel Sambuc BLOCK_BYREF_HAS_COPY_DISPOSE = (1 << 25), // compiler 52f4a2713aSLionel Sambuc BLOCK_BYREF_LAYOUT_MASK = (0xF << 28), // compiler 53f4a2713aSLionel Sambuc BLOCK_BYREF_LAYOUT_EXTENDED = (1 << 28), 54f4a2713aSLionel Sambuc BLOCK_BYREF_LAYOUT_NON_OBJECT = (2 << 28), 55f4a2713aSLionel Sambuc BLOCK_BYREF_LAYOUT_STRONG = (3 << 28), 56f4a2713aSLionel Sambuc BLOCK_BYREF_LAYOUT_WEAK = (4 << 28), 57f4a2713aSLionel Sambuc BLOCK_BYREF_LAYOUT_UNRETAINED = (5 << 28) 58f4a2713aSLionel Sambuc }; 59f4a2713aSLionel Sambuc 60f4a2713aSLionel Sambuc enum BlockLiteralFlags { 61f4a2713aSLionel Sambuc BLOCK_HAS_COPY_DISPOSE = (1 << 25), 62f4a2713aSLionel Sambuc BLOCK_HAS_CXX_OBJ = (1 << 26), 63f4a2713aSLionel Sambuc BLOCK_IS_GLOBAL = (1 << 28), 64f4a2713aSLionel Sambuc BLOCK_USE_STRET = (1 << 29), 65f4a2713aSLionel Sambuc BLOCK_HAS_SIGNATURE = (1 << 30), 66f4a2713aSLionel Sambuc BLOCK_HAS_EXTENDED_LAYOUT = (1 << 31) 67f4a2713aSLionel Sambuc }; 68f4a2713aSLionel Sambuc class BlockFlags { 69f4a2713aSLionel Sambuc uint32_t flags; 70f4a2713aSLionel Sambuc 71f4a2713aSLionel Sambuc public: BlockFlags(uint32_t flags)72f4a2713aSLionel Sambuc BlockFlags(uint32_t flags) : flags(flags) {} BlockFlags()73f4a2713aSLionel Sambuc BlockFlags() : flags(0) {} BlockFlags(BlockLiteralFlags flag)74f4a2713aSLionel Sambuc BlockFlags(BlockLiteralFlags flag) : flags(flag) {} BlockFlags(BlockByrefFlags flag)75f4a2713aSLionel Sambuc BlockFlags(BlockByrefFlags flag) : flags(flag) {} 76f4a2713aSLionel Sambuc getBitMask()77f4a2713aSLionel Sambuc uint32_t getBitMask() const { return flags; } empty()78f4a2713aSLionel Sambuc bool empty() const { return flags == 0; } 79f4a2713aSLionel Sambuc 80f4a2713aSLionel Sambuc friend BlockFlags operator|(BlockFlags l, BlockFlags r) { 81f4a2713aSLionel Sambuc return BlockFlags(l.flags | r.flags); 82f4a2713aSLionel Sambuc } 83f4a2713aSLionel Sambuc friend BlockFlags &operator|=(BlockFlags &l, BlockFlags r) { 84f4a2713aSLionel Sambuc l.flags |= r.flags; 85f4a2713aSLionel Sambuc return l; 86f4a2713aSLionel Sambuc } 87f4a2713aSLionel Sambuc friend bool operator&(BlockFlags l, BlockFlags r) { 88f4a2713aSLionel Sambuc return (l.flags & r.flags); 89f4a2713aSLionel Sambuc } 90f4a2713aSLionel Sambuc bool operator==(BlockFlags r) { 91f4a2713aSLionel Sambuc return (flags == r.flags); 92f4a2713aSLionel Sambuc } 93f4a2713aSLionel Sambuc }; 94f4a2713aSLionel Sambuc inline BlockFlags operator|(BlockLiteralFlags l, BlockLiteralFlags r) { 95f4a2713aSLionel Sambuc return BlockFlags(l) | BlockFlags(r); 96f4a2713aSLionel Sambuc } 97f4a2713aSLionel Sambuc 98f4a2713aSLionel Sambuc enum BlockFieldFlag_t { 99f4a2713aSLionel Sambuc BLOCK_FIELD_IS_OBJECT = 0x03, /* id, NSObject, __attribute__((NSObject)), 100f4a2713aSLionel Sambuc block, ... */ 101f4a2713aSLionel Sambuc BLOCK_FIELD_IS_BLOCK = 0x07, /* a block variable */ 102f4a2713aSLionel Sambuc 103f4a2713aSLionel Sambuc BLOCK_FIELD_IS_BYREF = 0x08, /* the on stack structure holding the __block 104f4a2713aSLionel Sambuc variable */ 105f4a2713aSLionel Sambuc BLOCK_FIELD_IS_WEAK = 0x10, /* declared __weak, only used in byref copy 106f4a2713aSLionel Sambuc helpers */ 107f4a2713aSLionel Sambuc BLOCK_FIELD_IS_ARC = 0x40, /* field has ARC-specific semantics */ 108f4a2713aSLionel Sambuc BLOCK_BYREF_CALLER = 128, /* called from __block (byref) copy/dispose 109f4a2713aSLionel Sambuc support routines */ 110f4a2713aSLionel Sambuc BLOCK_BYREF_CURRENT_MAX = 256 111f4a2713aSLionel Sambuc }; 112f4a2713aSLionel Sambuc 113f4a2713aSLionel Sambuc class BlockFieldFlags { 114f4a2713aSLionel Sambuc uint32_t flags; 115f4a2713aSLionel Sambuc BlockFieldFlags(uint32_t flags)116f4a2713aSLionel Sambuc BlockFieldFlags(uint32_t flags) : flags(flags) {} 117f4a2713aSLionel Sambuc public: BlockFieldFlags()118f4a2713aSLionel Sambuc BlockFieldFlags() : flags(0) {} BlockFieldFlags(BlockFieldFlag_t flag)119f4a2713aSLionel Sambuc BlockFieldFlags(BlockFieldFlag_t flag) : flags(flag) {} 120f4a2713aSLionel Sambuc getBitMask()121f4a2713aSLionel Sambuc uint32_t getBitMask() const { return flags; } empty()122f4a2713aSLionel Sambuc bool empty() const { return flags == 0; } 123f4a2713aSLionel Sambuc 124f4a2713aSLionel Sambuc /// Answers whether the flags indicate that this field is an object 125f4a2713aSLionel Sambuc /// or block pointer that requires _Block_object_assign/dispose. isSpecialPointer()126f4a2713aSLionel Sambuc bool isSpecialPointer() const { return flags & BLOCK_FIELD_IS_OBJECT; } 127f4a2713aSLionel Sambuc 128f4a2713aSLionel Sambuc friend BlockFieldFlags operator|(BlockFieldFlags l, BlockFieldFlags r) { 129f4a2713aSLionel Sambuc return BlockFieldFlags(l.flags | r.flags); 130f4a2713aSLionel Sambuc } 131f4a2713aSLionel Sambuc friend BlockFieldFlags &operator|=(BlockFieldFlags &l, BlockFieldFlags r) { 132f4a2713aSLionel Sambuc l.flags |= r.flags; 133f4a2713aSLionel Sambuc return l; 134f4a2713aSLionel Sambuc } 135f4a2713aSLionel Sambuc friend bool operator&(BlockFieldFlags l, BlockFieldFlags r) { 136f4a2713aSLionel Sambuc return (l.flags & r.flags); 137f4a2713aSLionel Sambuc } 138f4a2713aSLionel Sambuc }; 139f4a2713aSLionel Sambuc inline BlockFieldFlags operator|(BlockFieldFlag_t l, BlockFieldFlag_t r) { 140f4a2713aSLionel Sambuc return BlockFieldFlags(l) | BlockFieldFlags(r); 141f4a2713aSLionel Sambuc } 142f4a2713aSLionel Sambuc 143f4a2713aSLionel Sambuc /// CGBlockInfo - Information to generate a block literal. 144f4a2713aSLionel Sambuc class CGBlockInfo { 145f4a2713aSLionel Sambuc public: 146f4a2713aSLionel Sambuc /// Name - The name of the block, kindof. 147f4a2713aSLionel Sambuc StringRef Name; 148f4a2713aSLionel Sambuc 149f4a2713aSLionel Sambuc /// The field index of 'this' within the block, if there is one. 150f4a2713aSLionel Sambuc unsigned CXXThisIndex; 151f4a2713aSLionel Sambuc 152f4a2713aSLionel Sambuc class Capture { 153f4a2713aSLionel Sambuc uintptr_t Data; 154f4a2713aSLionel Sambuc EHScopeStack::stable_iterator Cleanup; 155f4a2713aSLionel Sambuc 156f4a2713aSLionel Sambuc public: isIndex()157f4a2713aSLionel Sambuc bool isIndex() const { return (Data & 1) != 0; } isConstant()158f4a2713aSLionel Sambuc bool isConstant() const { return !isIndex(); } getIndex()159f4a2713aSLionel Sambuc unsigned getIndex() const { assert(isIndex()); return Data >> 1; } getConstant()160f4a2713aSLionel Sambuc llvm::Value *getConstant() const { 161f4a2713aSLionel Sambuc assert(isConstant()); 162f4a2713aSLionel Sambuc return reinterpret_cast<llvm::Value*>(Data); 163f4a2713aSLionel Sambuc } getCleanup()164f4a2713aSLionel Sambuc EHScopeStack::stable_iterator getCleanup() const { 165f4a2713aSLionel Sambuc assert(isIndex()); 166f4a2713aSLionel Sambuc return Cleanup; 167f4a2713aSLionel Sambuc } setCleanup(EHScopeStack::stable_iterator cleanup)168f4a2713aSLionel Sambuc void setCleanup(EHScopeStack::stable_iterator cleanup) { 169f4a2713aSLionel Sambuc assert(isIndex()); 170f4a2713aSLionel Sambuc Cleanup = cleanup; 171f4a2713aSLionel Sambuc } 172f4a2713aSLionel Sambuc makeIndex(unsigned index)173f4a2713aSLionel Sambuc static Capture makeIndex(unsigned index) { 174f4a2713aSLionel Sambuc Capture v; 175f4a2713aSLionel Sambuc v.Data = (index << 1) | 1; 176f4a2713aSLionel Sambuc return v; 177f4a2713aSLionel Sambuc } 178f4a2713aSLionel Sambuc makeConstant(llvm::Value * value)179f4a2713aSLionel Sambuc static Capture makeConstant(llvm::Value *value) { 180f4a2713aSLionel Sambuc Capture v; 181f4a2713aSLionel Sambuc v.Data = reinterpret_cast<uintptr_t>(value); 182f4a2713aSLionel Sambuc return v; 183f4a2713aSLionel Sambuc } 184f4a2713aSLionel Sambuc }; 185f4a2713aSLionel Sambuc 186f4a2713aSLionel Sambuc /// CanBeGlobal - True if the block can be global, i.e. it has 187f4a2713aSLionel Sambuc /// no non-constant captures. 188f4a2713aSLionel Sambuc bool CanBeGlobal : 1; 189f4a2713aSLionel Sambuc 190f4a2713aSLionel Sambuc /// True if the block needs a custom copy or dispose function. 191f4a2713aSLionel Sambuc bool NeedsCopyDispose : 1; 192f4a2713aSLionel Sambuc 193f4a2713aSLionel Sambuc /// HasCXXObject - True if the block's custom copy/dispose functions 194f4a2713aSLionel Sambuc /// need to be run even in GC mode. 195f4a2713aSLionel Sambuc bool HasCXXObject : 1; 196f4a2713aSLionel Sambuc 197f4a2713aSLionel Sambuc /// UsesStret : True if the block uses an stret return. Mutable 198f4a2713aSLionel Sambuc /// because it gets set later in the block-creation process. 199f4a2713aSLionel Sambuc mutable bool UsesStret : 1; 200f4a2713aSLionel Sambuc 201f4a2713aSLionel Sambuc /// HasCapturedVariableLayout : True if block has captured variables 202f4a2713aSLionel Sambuc /// and their layout meta-data has been generated. 203f4a2713aSLionel Sambuc bool HasCapturedVariableLayout : 1; 204f4a2713aSLionel Sambuc 205f4a2713aSLionel Sambuc /// The mapping of allocated indexes within the block. 206f4a2713aSLionel Sambuc llvm::DenseMap<const VarDecl*, Capture> Captures; 207f4a2713aSLionel Sambuc 208f4a2713aSLionel Sambuc llvm::AllocaInst *Address; 209f4a2713aSLionel Sambuc llvm::StructType *StructureType; 210f4a2713aSLionel Sambuc const BlockDecl *Block; 211f4a2713aSLionel Sambuc const BlockExpr *BlockExpression; 212f4a2713aSLionel Sambuc CharUnits BlockSize; 213f4a2713aSLionel Sambuc CharUnits BlockAlign; 214f4a2713aSLionel Sambuc 215f4a2713aSLionel Sambuc // Offset of the gap caused by block header having a smaller 216f4a2713aSLionel Sambuc // alignment than the alignment of the block descriptor. This 217f4a2713aSLionel Sambuc // is the gap offset before the first capturued field. 218f4a2713aSLionel Sambuc CharUnits BlockHeaderForcedGapOffset; 219f4a2713aSLionel Sambuc // Gap size caused by aligning first field after block header. 220f4a2713aSLionel Sambuc // This could be zero if no forced alignment is required. 221f4a2713aSLionel Sambuc CharUnits BlockHeaderForcedGapSize; 222f4a2713aSLionel Sambuc 223f4a2713aSLionel Sambuc /// An instruction which dominates the full-expression that the 224f4a2713aSLionel Sambuc /// block is inside. 225f4a2713aSLionel Sambuc llvm::Instruction *DominatingIP; 226f4a2713aSLionel Sambuc 227f4a2713aSLionel Sambuc /// The next block in the block-info chain. Invalid if this block 228f4a2713aSLionel Sambuc /// info is not part of the CGF's block-info chain, which is true 229f4a2713aSLionel Sambuc /// if it corresponds to a global block or a block whose expression 230f4a2713aSLionel Sambuc /// has been encountered. 231f4a2713aSLionel Sambuc CGBlockInfo *NextBlockInfo; 232f4a2713aSLionel Sambuc getCapture(const VarDecl * var)233f4a2713aSLionel Sambuc const Capture &getCapture(const VarDecl *var) const { 234f4a2713aSLionel Sambuc return const_cast<CGBlockInfo*>(this)->getCapture(var); 235f4a2713aSLionel Sambuc } getCapture(const VarDecl * var)236f4a2713aSLionel Sambuc Capture &getCapture(const VarDecl *var) { 237f4a2713aSLionel Sambuc llvm::DenseMap<const VarDecl*, Capture>::iterator 238f4a2713aSLionel Sambuc it = Captures.find(var); 239f4a2713aSLionel Sambuc assert(it != Captures.end() && "no entry for variable!"); 240f4a2713aSLionel Sambuc return it->second; 241f4a2713aSLionel Sambuc } 242f4a2713aSLionel Sambuc getBlockDecl()243f4a2713aSLionel Sambuc const BlockDecl *getBlockDecl() const { return Block; } getBlockExpr()244f4a2713aSLionel Sambuc const BlockExpr *getBlockExpr() const { 245f4a2713aSLionel Sambuc assert(BlockExpression); 246f4a2713aSLionel Sambuc assert(BlockExpression->getBlockDecl() == Block); 247f4a2713aSLionel Sambuc return BlockExpression; 248f4a2713aSLionel Sambuc } 249f4a2713aSLionel Sambuc 250f4a2713aSLionel Sambuc CGBlockInfo(const BlockDecl *blockDecl, StringRef Name); 251f4a2713aSLionel Sambuc }; 252f4a2713aSLionel Sambuc 253f4a2713aSLionel Sambuc } // end namespace CodeGen 254f4a2713aSLionel Sambuc } // end namespace clang 255f4a2713aSLionel Sambuc 256f4a2713aSLionel Sambuc #endif 257