clang API Documentation

CGBlocks.h
Go to the documentation of this file.
00001 //===-- CGBlocks.h - state for LLVM CodeGen for blocks ----------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This is the internal state used for llvm translation for block literals.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_CLANG_LIB_CODEGEN_CGBLOCKS_H
00015 #define LLVM_CLANG_LIB_CODEGEN_CGBLOCKS_H
00016 
00017 #include "CGBuilder.h"
00018 #include "CGCall.h"
00019 #include "CGValue.h"
00020 #include "CodeGenFunction.h"
00021 #include "CodeGenTypes.h"
00022 #include "clang/AST/CharUnits.h"
00023 #include "clang/AST/Expr.h"
00024 #include "clang/AST/ExprCXX.h"
00025 #include "clang/AST/ExprObjC.h"
00026 #include "clang/AST/Type.h"
00027 #include "clang/Basic/TargetInfo.h"
00028 #include "llvm/IR/Module.h"
00029 
00030 namespace llvm {
00031 class Module;
00032 class Constant;
00033 class Function;
00034 class GlobalValue;
00035 class DataLayout;
00036 class FunctionType;
00037 class PointerType;
00038 class Value;
00039 class LLVMContext;
00040 }
00041 
00042 namespace clang {
00043 
00044 namespace CodeGen {
00045 
00046 class CodeGenModule;
00047 class CGBlockInfo;
00048 
00049 // Flags stored in __block variables.
00050 enum BlockByrefFlags {
00051   BLOCK_BYREF_HAS_COPY_DISPOSE         = (1   << 25), // compiler
00052   BLOCK_BYREF_LAYOUT_MASK              = (0xF << 28), // compiler
00053   BLOCK_BYREF_LAYOUT_EXTENDED          = (1   << 28),
00054   BLOCK_BYREF_LAYOUT_NON_OBJECT        = (2   << 28),
00055   BLOCK_BYREF_LAYOUT_STRONG            = (3   << 28),
00056   BLOCK_BYREF_LAYOUT_WEAK              = (4   << 28),
00057   BLOCK_BYREF_LAYOUT_UNRETAINED        = (5   << 28)
00058 };
00059 
00060 enum BlockLiteralFlags {
00061   BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
00062   BLOCK_HAS_CXX_OBJ =       (1 << 26),
00063   BLOCK_IS_GLOBAL =         (1 << 28),
00064   BLOCK_USE_STRET =         (1 << 29),
00065   BLOCK_HAS_SIGNATURE  =    (1 << 30),
00066   BLOCK_HAS_EXTENDED_LAYOUT = (1 << 31)
00067 };
00068 class BlockFlags {
00069   uint32_t flags;
00070 
00071 public:
00072   BlockFlags(uint32_t flags) : flags(flags) {}
00073   BlockFlags() : flags(0) {}
00074   BlockFlags(BlockLiteralFlags flag) : flags(flag) {}
00075   BlockFlags(BlockByrefFlags flag) : flags(flag) {}
00076   
00077   uint32_t getBitMask() const { return flags; }
00078   bool empty() const { return flags == 0; }
00079 
00080   friend BlockFlags operator|(BlockFlags l, BlockFlags r) {
00081     return BlockFlags(l.flags | r.flags);
00082   }
00083   friend BlockFlags &operator|=(BlockFlags &l, BlockFlags r) {
00084     l.flags |= r.flags;
00085     return l;
00086   }
00087   friend bool operator&(BlockFlags l, BlockFlags r) {
00088     return (l.flags & r.flags);
00089   }
00090   bool operator==(BlockFlags r) {
00091     return (flags == r.flags);
00092   }
00093 };
00094 inline BlockFlags operator|(BlockLiteralFlags l, BlockLiteralFlags r) {
00095   return BlockFlags(l) | BlockFlags(r);
00096 }
00097 
00098 enum BlockFieldFlag_t {
00099   BLOCK_FIELD_IS_OBJECT   = 0x03,  /* id, NSObject, __attribute__((NSObject)),
00100                                     block, ... */
00101   BLOCK_FIELD_IS_BLOCK    = 0x07,  /* a block variable */
00102 
00103   BLOCK_FIELD_IS_BYREF    = 0x08,  /* the on stack structure holding the __block
00104                                     variable */
00105   BLOCK_FIELD_IS_WEAK     = 0x10,  /* declared __weak, only used in byref copy
00106                                     helpers */
00107   BLOCK_FIELD_IS_ARC      = 0x40,  /* field has ARC-specific semantics */
00108   BLOCK_BYREF_CALLER      = 128,   /* called from __block (byref) copy/dispose
00109                                       support routines */
00110   BLOCK_BYREF_CURRENT_MAX = 256
00111 };
00112 
00113 class BlockFieldFlags {
00114   uint32_t flags;
00115 
00116   BlockFieldFlags(uint32_t flags) : flags(flags) {}
00117 public:
00118   BlockFieldFlags() : flags(0) {}
00119   BlockFieldFlags(BlockFieldFlag_t flag) : flags(flag) {}
00120 
00121   uint32_t getBitMask() const { return flags; }
00122   bool empty() const { return flags == 0; }
00123 
00124   /// Answers whether the flags indicate that this field is an object
00125   /// or block pointer that requires _Block_object_assign/dispose.
00126   bool isSpecialPointer() const { return flags & BLOCK_FIELD_IS_OBJECT; }
00127 
00128   friend BlockFieldFlags operator|(BlockFieldFlags l, BlockFieldFlags r) {
00129     return BlockFieldFlags(l.flags | r.flags);
00130   }
00131   friend BlockFieldFlags &operator|=(BlockFieldFlags &l, BlockFieldFlags r) {
00132     l.flags |= r.flags;
00133     return l;
00134   }
00135   friend bool operator&(BlockFieldFlags l, BlockFieldFlags r) {
00136     return (l.flags & r.flags);
00137   }
00138 };
00139 inline BlockFieldFlags operator|(BlockFieldFlag_t l, BlockFieldFlag_t r) {
00140   return BlockFieldFlags(l) | BlockFieldFlags(r);
00141 }
00142 
00143 /// CGBlockInfo - Information to generate a block literal.
00144 class CGBlockInfo {
00145 public:
00146   /// Name - The name of the block, kindof.
00147   StringRef Name;
00148 
00149   /// The field index of 'this' within the block, if there is one.
00150   unsigned CXXThisIndex;
00151 
00152   class Capture {
00153     uintptr_t Data;
00154     EHScopeStack::stable_iterator Cleanup;
00155 
00156   public:
00157     bool isIndex() const { return (Data & 1) != 0; }
00158     bool isConstant() const { return !isIndex(); }
00159     unsigned getIndex() const { assert(isIndex()); return Data >> 1; }
00160     llvm::Value *getConstant() const {
00161       assert(isConstant());
00162       return reinterpret_cast<llvm::Value*>(Data);
00163     }
00164     EHScopeStack::stable_iterator getCleanup() const {
00165       assert(isIndex());
00166       return Cleanup;
00167     }
00168     void setCleanup(EHScopeStack::stable_iterator cleanup) {
00169       assert(isIndex());
00170       Cleanup = cleanup;
00171     }
00172 
00173     static Capture makeIndex(unsigned index) {
00174       Capture v;
00175       v.Data = (index << 1) | 1;
00176       return v;
00177     }
00178 
00179     static Capture makeConstant(llvm::Value *value) {
00180       Capture v;
00181       v.Data = reinterpret_cast<uintptr_t>(value);
00182       return v;
00183     }    
00184   };
00185 
00186   /// CanBeGlobal - True if the block can be global, i.e. it has
00187   /// no non-constant captures.
00188   bool CanBeGlobal : 1;
00189 
00190   /// True if the block needs a custom copy or dispose function.
00191   bool NeedsCopyDispose : 1;
00192 
00193   /// HasCXXObject - True if the block's custom copy/dispose functions
00194   /// need to be run even in GC mode.
00195   bool HasCXXObject : 1;
00196 
00197   /// UsesStret : True if the block uses an stret return.  Mutable
00198   /// because it gets set later in the block-creation process.
00199   mutable bool UsesStret : 1;
00200   
00201   /// HasCapturedVariableLayout : True if block has captured variables
00202   /// and their layout meta-data has been generated.
00203   bool HasCapturedVariableLayout : 1;
00204 
00205   /// The mapping of allocated indexes within the block.
00206   llvm::DenseMap<const VarDecl*, Capture> Captures;  
00207 
00208   llvm::AllocaInst *Address;
00209   llvm::StructType *StructureType;
00210   const BlockDecl *Block;
00211   const BlockExpr *BlockExpression;
00212   CharUnits BlockSize;
00213   CharUnits BlockAlign;
00214   
00215   // Offset of the gap caused by block header having a smaller
00216   // alignment than the alignment of the block descriptor. This
00217   // is the gap offset before the first capturued field.
00218   CharUnits BlockHeaderForcedGapOffset;
00219   // Gap size caused by aligning first field after block header.
00220   // This could be zero if no forced alignment is required.
00221   CharUnits BlockHeaderForcedGapSize;
00222 
00223   /// An instruction which dominates the full-expression that the
00224   /// block is inside.
00225   llvm::Instruction *DominatingIP;
00226 
00227   /// The next block in the block-info chain.  Invalid if this block
00228   /// info is not part of the CGF's block-info chain, which is true
00229   /// if it corresponds to a global block or a block whose expression
00230   /// has been encountered.
00231   CGBlockInfo *NextBlockInfo;
00232 
00233   const Capture &getCapture(const VarDecl *var) const {
00234     return const_cast<CGBlockInfo*>(this)->getCapture(var);
00235   }
00236   Capture &getCapture(const VarDecl *var) {
00237     llvm::DenseMap<const VarDecl*, Capture>::iterator
00238       it = Captures.find(var);
00239     assert(it != Captures.end() && "no entry for variable!");
00240     return it->second;
00241   }
00242 
00243   const BlockDecl *getBlockDecl() const { return Block; }
00244   const BlockExpr *getBlockExpr() const {
00245     assert(BlockExpression);
00246     assert(BlockExpression->getBlockDecl() == Block);
00247     return BlockExpression;
00248   }
00249 
00250   CGBlockInfo(const BlockDecl *blockDecl, StringRef Name);
00251 };
00252 
00253 }  // end namespace CodeGen
00254 }  // end namespace clang
00255 
00256 #endif