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