//===--- CGBlocks.cpp - Emit LLVM Code for declarations -------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This contains code to emit blocks.
//
//===----------------------------------------------------------------------===//
#include "CGDebugInfo.h"
#include "CodeGenFunction.h"
#include "CGObjCRuntime.h"
#include "CodeGenModule.h"
#include "clang/AST/DeclObjC.h"
#include "llvm/Module.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/Target/TargetData.h"
#include <algorithm>
using namespace clang;
using namespace CodeGen;
/// CGBlockInfo - Information to generate a block literal.
class clang::CodeGen::CGBlockInfo {
public:
/// Name - The name of the block, kindof.
const char *Name;
/// DeclRefs - Variables from parent scopes that have been
/// imported into this block.
llvm::SmallVector<const BlockDeclRefExpr *, 8> DeclRefs;
/// InnerBlocks - This block and the blocks it encloses.
llvm::SmallPtrSet<const DeclContext *, 4> InnerBlocks;
/// CXXThisRef - Non-null if 'this' was required somewhere, in
/// which case this is that expression.
const CXXThisExpr *CXXThisRef;
/// NeedsObjCSelf - True if something in this block has an implicit
/// reference to 'self'.
bool NeedsObjCSelf;
/// These are initialized by GenerateBlockFunction.
bool BlockHasCopyDispose;
CharUnits BlockSize;
CharUnits BlockAlign;
llvm::SmallVector<const Expr*, 8> BlockLayout;
CGBlockInfo(const char *Name);
};
CGBlockInfo::CGBlockInfo(const char *N)
: Name(N), CXXThisRef(0), NeedsObjCSelf(false) {
// Skip asm prefix, if any.
if (Name && Name[0] == '\01')
++Name;
}
llvm::Constant *CodeGenFunction::
BuildDescriptorBlockDecl(const BlockExpr *BE, bool BlockHasCopyDispose, CharUnits Size,
const llvm::StructType* Ty,
std::vector<HelperInfo> *NoteForHelper) {
const llvm::Type *UnsignedLongTy
= CGM.getTypes().ConvertType(getContext().UnsignedLongTy);
llvm::Constant *C;
std::vector<llvm::Constant*> Elts;
// reserved
C = llvm::ConstantInt::get(UnsignedLongTy, 0);
Elts.push_back(C);
// Size
// FIXME: What is the right way to say this doesn't fit? We should give
// a user diagnostic in that case. Better fix would be to change the
// API to size_t.
C = ll