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