//===-- CodeGenFunction.h - Per-Function state for LLVM CodeGen -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This is the internal per-function state used for llvm translation.
//
//===----------------------------------------------------------------------===//
#ifndef CLANG_CODEGEN_CODEGENFUNCTION_H
#define CLANG_CODEGEN_CODEGENFUNCTION_H
#include "clang/AST/Type.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/ValueHandle.h"
#include <map>
#include "CodeGenModule.h"
#include "CGBlocks.h"
#include "CGBuilder.h"
#include "CGCall.h"
#include "CGCXX.h"
#include "CGValue.h"
namespace llvm {
class BasicBlock;
class LLVMContext;
class Module;
class SwitchInst;
class Value;
}
namespace clang {
class ASTContext;
class CXXDestructorDecl;
class Decl;
class EnumConstantDecl;
class FunctionDecl;
class FunctionProtoType;
class LabelStmt;
class ObjCContainerDecl;
class ObjCInterfaceDecl;
class ObjCIvarDecl;
class ObjCMethodDecl;
class ObjCImplementationDecl;
class ObjCPropertyImplDecl;
class TargetInfo;
class VarDecl;
class ObjCForCollectionStmt;
class ObjCAtTryStmt;
class ObjCAtThrowStmt;
class ObjCAtSynchronizedStmt;
namespace CodeGen {
class CodeGenModule;
class CodeGenTypes;
class CGDebugInfo;
class CGFunctionInfo;
class CGRecordLayout;
/// CodeGenFunction - This class organizes the per-function state that is used
/// while generating LLVM code.
class CodeGenFunction : public BlockFunction {
CodeGenFunction(const CodeGenFunction&); // DO NOT IMPLEMENT
void operator=(const CodeGenFunction&); // DO NOT IMPLEMENT
public:
CodeGenModule &CGM; // Per-module state.
TargetInfo &Target;
typedef std::pair<llvm::Value *, llvm::Value *> ComplexPairTy;
CGBuilderTy Builder;
/// CurFuncDecl - Holds the Decl for the current function or ObjC method.
/// This excludes BlockDecls.
const Decl *CurFuncDecl;
/// CurCodeDecl - This is the inner-most code context, which includes blocks.
const Decl *CurCodeDecl;
const CGFunctionInfo *CurFnInfo;
QualType FnRetTy;
llvm::Function *CurFn;
/// ReturnBlock - Unified return block.
llvm::BasicBlock *ReturnBlock;
/// ReturnValue - The temporary alloca to hold the return value. This is null
/// iff the function has no return value.
llvm::Instruction *ReturnValue;
/// AllocaInsertPoint - This is an instruction in the entry block before which
/// we prefer to insert allocas.
llvm::AssertingVH<llvm::Instruction> AllocaInsertPt;
const llvm::Type *LLVMIntTy;
uint32_t LLVMPointerWidth;
public:
/// ObjCEHValueStack - Stack of Objective-C exception values, used for
/// rethrows.
llvm::SmallVector<llvm::Value*, 8> ObjCEHValueStack;
/// PushCleanupBlock - Push a new cleanup entry on the stack and set the
/// passed in block as the cleanup block.
void PushCleanupBlock(llvm::BasicBlock *CleanupBlock);
/// CleanupBlockInfo - A struct representing a popped cleanup block.
struct CleanupBlockInfo {
/// CleanupBlock - the cleanup block
llvm::BasicBlock *CleanupBlock;
/// SwitchBlock - the block (if any) containing the switch instruction used
/// for jumping to the final destination.
llvm::BasicBlock *SwitchBlock;
/// EndBlock - the default destination for the switch instruction.
llvm::BasicBlock *EndBlock;
CleanupBlockInfo(llvm::BasicBlock *cb, llvm::BasicBlock *sb,
llvm::BasicBlock *eb)
: CleanupBlock(cb), SwitchBlock(sb), EndBlock(eb) {}
};
/// PopCleanupBlock - Will pop the cleanup entry on the stack, process all
/// branch fixups and return a block info struct with the switch block and end
/// block.
CleanupBlockInfo PopCleanupBlock();
/// CleanupScope - RAII object that will create a cleanup block and set the
/// insert point to that block. When destructed, it sets the insert point to
/// the previous block and pushes a new cleanup entry on the stack.
class CleanupScope {
CodeGenFunction& CGF;
llvm::BasicBlock *CurBB;
llvm::BasicBlock *CleanupBB;
public:
CleanupScope(CodeGenFunction &cgf)
: CGF(cgf), CurBB(CGF.Builder.GetInsertBlock()) {
CleanupBB = CGF.createBasicBlock("cleanup");
CGF.Builder.SetInsertPoint(CleanupBB);
}
~CleanupScope() {
CGF.PushCleanupBlock(CleanupBB);
// FIXME: This is silly, move this into the builder.
if (CurBB)
CGF.Builder.SetInsertPoint(CurBB);
else
CGF.Builder.ClearInsertionPoint();
}
};
/// EmitCleanupBlocks - Takes the old cleanup stack size and emits the cleanup
/// blocks that have been added.
void EmitCleanupBlocks(size_t OldCleanupStackSize);