1193326Sed//===-- CGBlocks.h - state for LLVM CodeGen for blocks ----------*- C++ -*-===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This is the internal state used for llvm translation for block literals. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed 14193326Sed#ifndef CLANG_CODEGEN_CGBLOCKS_H 15193326Sed#define CLANG_CODEGEN_CGBLOCKS_H 16193326Sed 17249423Sdim#include "CGBuilder.h" 18249423Sdim#include "CGCall.h" 19249423Sdim#include "CGValue.h" 20249423Sdim#include "CodeGenFunction.h" 21193326Sed#include "CodeGenTypes.h" 22202379Srdivacky#include "clang/AST/CharUnits.h" 23193326Sed#include "clang/AST/Expr.h" 24193326Sed#include "clang/AST/ExprCXX.h" 25193326Sed#include "clang/AST/ExprObjC.h" 26249423Sdim#include "clang/AST/Type.h" 27249423Sdim#include "clang/Basic/TargetInfo.h" 28249423Sdim#include "llvm/IR/Module.h" 29193326Sed 30193326Sednamespace llvm { 31193326Sed class Module; 32193326Sed class Constant; 33193326Sed class Function; 34193326Sed class GlobalValue; 35243830Sdim class DataLayout; 36193326Sed class FunctionType; 37207619Srdivacky class PointerType; 38193326Sed class Value; 39198092Srdivacky class LLVMContext; 40193326Sed} 41193326Sed 42193326Sednamespace clang { 43193326Sed 44193326Sednamespace CodeGen { 45218893Sdim 46193326Sedclass CodeGenModule; 47218893Sdimclass CGBlockInfo; 48193326Sed 49243830Sdim// Flags stored in __block variables. 50243830Sdimenum BlockByrefFlags { 51243830Sdim BLOCK_BYREF_HAS_COPY_DISPOSE = (1 << 25), // compiler 52243830Sdim BLOCK_BYREF_LAYOUT_MASK = (0xF << 28), // compiler 53243830Sdim BLOCK_BYREF_LAYOUT_EXTENDED = (1 << 28), 54243830Sdim BLOCK_BYREF_LAYOUT_NON_OBJECT = (2 << 28), 55243830Sdim BLOCK_BYREF_LAYOUT_STRONG = (3 << 28), 56243830Sdim BLOCK_BYREF_LAYOUT_WEAK = (4 << 28), 57243830Sdim BLOCK_BYREF_LAYOUT_UNRETAINED = (5 << 28) 58243830Sdim}; 59243830Sdim 60243830Sdimenum BlockLiteralFlags { 61218893Sdim BLOCK_HAS_COPY_DISPOSE = (1 << 25), 62218893Sdim BLOCK_HAS_CXX_OBJ = (1 << 26), 63218893Sdim BLOCK_IS_GLOBAL = (1 << 28), 64218893Sdim BLOCK_USE_STRET = (1 << 29), 65243830Sdim BLOCK_HAS_SIGNATURE = (1 << 30), 66243830Sdim BLOCK_HAS_EXTENDED_LAYOUT = (1 << 31) 67193326Sed}; 68218893Sdimclass BlockFlags { 69218893Sdim uint32_t flags; 70193326Sed 71249423Sdimpublic: 72218893Sdim BlockFlags(uint32_t flags) : flags(flags) {} 73218893Sdim BlockFlags() : flags(0) {} 74243830Sdim BlockFlags(BlockLiteralFlags flag) : flags(flag) {} 75249423Sdim BlockFlags(BlockByrefFlags flag) : flags(flag) {} 76249423Sdim 77218893Sdim uint32_t getBitMask() const { return flags; } 78218893Sdim bool empty() const { return flags == 0; } 79198092Srdivacky 80218893Sdim friend BlockFlags operator|(BlockFlags l, BlockFlags r) { 81218893Sdim return BlockFlags(l.flags | r.flags); 82218893Sdim } 83218893Sdim friend BlockFlags &operator|=(BlockFlags &l, BlockFlags r) { 84218893Sdim l.flags |= r.flags; 85218893Sdim return l; 86218893Sdim } 87218893Sdim friend bool operator&(BlockFlags l, BlockFlags r) { 88218893Sdim return (l.flags & r.flags); 89218893Sdim } 90249423Sdim bool operator==(BlockFlags r) { 91249423Sdim return (flags == r.flags); 92249423Sdim } 93218893Sdim}; 94243830Sdiminline BlockFlags operator|(BlockLiteralFlags l, BlockLiteralFlags r) { 95218893Sdim return BlockFlags(l) | BlockFlags(r); 96218893Sdim} 97193326Sed 98218893Sdimenum BlockFieldFlag_t { 99218893Sdim BLOCK_FIELD_IS_OBJECT = 0x03, /* id, NSObject, __attribute__((NSObject)), 100218893Sdim block, ... */ 101218893Sdim BLOCK_FIELD_IS_BLOCK = 0x07, /* a block variable */ 102193326Sed 103218893Sdim BLOCK_FIELD_IS_BYREF = 0x08, /* the on stack structure holding the __block 104218893Sdim variable */ 105218893Sdim BLOCK_FIELD_IS_WEAK = 0x10, /* declared __weak, only used in byref copy 106218893Sdim helpers */ 107224145Sdim BLOCK_FIELD_IS_ARC = 0x40, /* field has ARC-specific semantics */ 108218893Sdim BLOCK_BYREF_CALLER = 128, /* called from __block (byref) copy/dispose 109218893Sdim support routines */ 110218893Sdim BLOCK_BYREF_CURRENT_MAX = 256 111218893Sdim}; 112204643Srdivacky 113218893Sdimclass BlockFieldFlags { 114218893Sdim uint32_t flags; 115193326Sed 116218893Sdim BlockFieldFlags(uint32_t flags) : flags(flags) {} 117218893Sdimpublic: 118218893Sdim BlockFieldFlags() : flags(0) {} 119218893Sdim BlockFieldFlags(BlockFieldFlag_t flag) : flags(flag) {} 120193326Sed 121218893Sdim uint32_t getBitMask() const { return flags; } 122218893Sdim bool empty() const { return flags == 0; } 123193576Sed 124218893Sdim /// Answers whether the flags indicate that this field is an object 125218893Sdim /// or block pointer that requires _Block_object_assign/dispose. 126218893Sdim bool isSpecialPointer() const { return flags & BLOCK_FIELD_IS_OBJECT; } 127218893Sdim 128218893Sdim friend BlockFieldFlags operator|(BlockFieldFlags l, BlockFieldFlags r) { 129218893Sdim return BlockFieldFlags(l.flags | r.flags); 130193326Sed } 131218893Sdim friend BlockFieldFlags &operator|=(BlockFieldFlags &l, BlockFieldFlags r) { 132218893Sdim l.flags |= r.flags; 133218893Sdim return l; 134218893Sdim } 135218893Sdim friend bool operator&(BlockFieldFlags l, BlockFieldFlags r) { 136218893Sdim return (l.flags & r.flags); 137218893Sdim } 138193326Sed}; 139218893Sdiminline BlockFieldFlags operator|(BlockFieldFlag_t l, BlockFieldFlag_t r) { 140218893Sdim return BlockFieldFlags(l) | BlockFieldFlags(r); 141218893Sdim} 142193326Sed 143218893Sdim/// CGBlockInfo - Information to generate a block literal. 144218893Sdimclass CGBlockInfo { 145193326Sedpublic: 146218893Sdim /// Name - The name of the block, kindof. 147249423Sdim StringRef Name; 148210299Sed 149218893Sdim /// The field index of 'this' within the block, if there is one. 150218893Sdim unsigned CXXThisIndex; 151193326Sed 152218893Sdim class Capture { 153218893Sdim uintptr_t Data; 154234353Sdim EHScopeStack::stable_iterator Cleanup; 155193326Sed 156218893Sdim public: 157218893Sdim bool isIndex() const { return (Data & 1) != 0; } 158218893Sdim bool isConstant() const { return !isIndex(); } 159218893Sdim unsigned getIndex() const { assert(isIndex()); return Data >> 1; } 160218893Sdim llvm::Value *getConstant() const { 161218893Sdim assert(isConstant()); 162218893Sdim return reinterpret_cast<llvm::Value*>(Data); 163218893Sdim } 164234353Sdim EHScopeStack::stable_iterator getCleanup() const { 165234353Sdim assert(isIndex()); 166234353Sdim return Cleanup; 167234353Sdim } 168234353Sdim void setCleanup(EHScopeStack::stable_iterator cleanup) { 169234353Sdim assert(isIndex()); 170234353Sdim Cleanup = cleanup; 171234353Sdim } 172193326Sed 173218893Sdim static Capture makeIndex(unsigned index) { 174218893Sdim Capture v; 175218893Sdim v.Data = (index << 1) | 1; 176218893Sdim return v; 177218893Sdim } 178193326Sed 179218893Sdim static Capture makeConstant(llvm::Value *value) { 180218893Sdim Capture v; 181218893Sdim v.Data = reinterpret_cast<uintptr_t>(value); 182218893Sdim return v; 183218893Sdim } 184218893Sdim }; 185193326Sed 186218893Sdim /// CanBeGlobal - True if the block can be global, i.e. it has 187218893Sdim /// no non-constant captures. 188218893Sdim bool CanBeGlobal : 1; 189193326Sed 190218893Sdim /// True if the block needs a custom copy or dispose function. 191218893Sdim bool NeedsCopyDispose : 1; 192193326Sed 193218893Sdim /// HasCXXObject - True if the block's custom copy/dispose functions 194218893Sdim /// need to be run even in GC mode. 195218893Sdim bool HasCXXObject : 1; 196208600Srdivacky 197221345Sdim /// UsesStret : True if the block uses an stret return. Mutable 198221345Sdim /// because it gets set later in the block-creation process. 199221345Sdim mutable bool UsesStret : 1; 200243830Sdim 201243830Sdim /// HasCapturedVariableLayout : True if block has captured variables 202243830Sdim /// and their layout meta-data has been generated. 203243830Sdim bool HasCapturedVariableLayout : 1; 204221345Sdim 205234353Sdim /// The mapping of allocated indexes within the block. 206234353Sdim llvm::DenseMap<const VarDecl*, Capture> Captures; 207234353Sdim 208234353Sdim llvm::AllocaInst *Address; 209226633Sdim llvm::StructType *StructureType; 210234353Sdim const BlockDecl *Block; 211234353Sdim const BlockExpr *BlockExpression; 212218893Sdim CharUnits BlockSize; 213218893Sdim CharUnits BlockAlign; 214249423Sdim 215249423Sdim // Offset of the gap caused by block header having a smaller 216249423Sdim // alignment than the alignment of the block descriptor. This 217249423Sdim // is the gap offset before the first capturued field. 218249423Sdim CharUnits BlockHeaderForcedGapOffset; 219249423Sdim // Gap size caused by aligning first field after block header. 220249423Sdim // This could be zero if no forced alignment is required. 221249423Sdim CharUnits BlockHeaderForcedGapSize; 222193326Sed 223234353Sdim /// An instruction which dominates the full-expression that the 224234353Sdim /// block is inside. 225234353Sdim llvm::Instruction *DominatingIP; 226234353Sdim 227234353Sdim /// The next block in the block-info chain. Invalid if this block 228234353Sdim /// info is not part of the CGF's block-info chain, which is true 229234353Sdim /// if it corresponds to a global block or a block whose expression 230234353Sdim /// has been encountered. 231234353Sdim CGBlockInfo *NextBlockInfo; 232234353Sdim 233218893Sdim const Capture &getCapture(const VarDecl *var) const { 234234353Sdim return const_cast<CGBlockInfo*>(this)->getCapture(var); 235234353Sdim } 236234353Sdim Capture &getCapture(const VarDecl *var) { 237234353Sdim llvm::DenseMap<const VarDecl*, Capture>::iterator 238218893Sdim it = Captures.find(var); 239218893Sdim assert(it != Captures.end() && "no entry for variable!"); 240218893Sdim return it->second; 241218893Sdim } 242193326Sed 243234353Sdim const BlockDecl *getBlockDecl() const { return Block; } 244234353Sdim const BlockExpr *getBlockExpr() const { 245234353Sdim assert(BlockExpression); 246234353Sdim assert(BlockExpression->getBlockDecl() == Block); 247234353Sdim return BlockExpression; 248234353Sdim } 249193326Sed 250249423Sdim CGBlockInfo(const BlockDecl *blockDecl, StringRef Name); 251193326Sed}; 252193326Sed 253193326Sed} // end namespace CodeGen 254193326Sed} // end namespace clang 255193326Sed 256193326Sed#endif 257