1f22ef01cSRoman Divacky //===--- CodeGenFunction.cpp - Emit LLVM Code from ASTs for a Function ----===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This coordinates the per-function state used while generating code.
11f22ef01cSRoman Divacky //
12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
13f22ef01cSRoman Divacky 
14f22ef01cSRoman Divacky #include "CodeGenFunction.h"
15f22ef01cSRoman Divacky #include "CodeGenModule.h"
16f22ef01cSRoman Divacky #include "CGDebugInfo.h"
17f22ef01cSRoman Divacky #include "clang/Basic/TargetInfo.h"
18f22ef01cSRoman Divacky #include "clang/AST/APValue.h"
19f22ef01cSRoman Divacky #include "clang/AST/ASTContext.h"
20f22ef01cSRoman Divacky #include "clang/AST/Decl.h"
21f22ef01cSRoman Divacky #include "clang/AST/DeclCXX.h"
22f22ef01cSRoman Divacky #include "clang/AST/StmtCXX.h"
23f22ef01cSRoman Divacky #include "llvm/Target/TargetData.h"
24f22ef01cSRoman Divacky using namespace clang;
25f22ef01cSRoman Divacky using namespace CodeGen;
26f22ef01cSRoman Divacky 
27f22ef01cSRoman Divacky CodeGenFunction::CodeGenFunction(CodeGenModule &cgm)
28f22ef01cSRoman Divacky   : BlockFunction(cgm, *this, Builder), CGM(cgm),
29f22ef01cSRoman Divacky     Target(CGM.getContext().Target),
30f22ef01cSRoman Divacky     Builder(cgm.getModule().getContext()),
31f22ef01cSRoman Divacky     DebugInfo(0), IndirectBranch(0),
32f22ef01cSRoman Divacky     SwitchInsn(0), CaseRangeBlock(0), InvokeDest(0),
33f22ef01cSRoman Divacky     CXXThisDecl(0), CXXThisValue(0), CXXVTTDecl(0), CXXVTTValue(0),
34f22ef01cSRoman Divacky     ConditionalBranchLevel(0), TerminateHandler(0), TrapBB(0),
35f22ef01cSRoman Divacky     UniqueAggrDestructorCount(0) {
36f22ef01cSRoman Divacky   LLVMIntTy = ConvertType(getContext().IntTy);
37f22ef01cSRoman Divacky   LLVMPointerWidth = Target.getPointerWidth(0);
38f22ef01cSRoman Divacky   Exceptions = getContext().getLangOptions().Exceptions;
39f22ef01cSRoman Divacky   CatchUndefined = getContext().getLangOptions().CatchUndefined;
40f22ef01cSRoman Divacky   CGM.getMangleContext().startNewFunction();
41f22ef01cSRoman Divacky }
42f22ef01cSRoman Divacky 
43f22ef01cSRoman Divacky ASTContext &CodeGenFunction::getContext() const {
44f22ef01cSRoman Divacky   return CGM.getContext();
45f22ef01cSRoman Divacky }
46f22ef01cSRoman Divacky 
47f22ef01cSRoman Divacky 
48f22ef01cSRoman Divacky llvm::BasicBlock *CodeGenFunction::getBasicBlockForLabel(const LabelStmt *S) {
49f22ef01cSRoman Divacky   llvm::BasicBlock *&BB = LabelMap[S];
50f22ef01cSRoman Divacky   if (BB) return BB;
51f22ef01cSRoman Divacky 
52f22ef01cSRoman Divacky   // Create, but don't insert, the new block.
53f22ef01cSRoman Divacky   return BB = createBasicBlock(S->getName());
54f22ef01cSRoman Divacky }
55f22ef01cSRoman Divacky 
56f22ef01cSRoman Divacky llvm::Value *CodeGenFunction::GetAddrOfLocalVar(const VarDecl *VD) {
57f22ef01cSRoman Divacky   llvm::Value *Res = LocalDeclMap[VD];
58f22ef01cSRoman Divacky   assert(Res && "Invalid argument to GetAddrOfLocalVar(), no decl!");
59f22ef01cSRoman Divacky   return Res;
60f22ef01cSRoman Divacky }
61f22ef01cSRoman Divacky 
62f22ef01cSRoman Divacky llvm::Constant *
63f22ef01cSRoman Divacky CodeGenFunction::GetAddrOfStaticLocalVar(const VarDecl *BVD) {
64f22ef01cSRoman Divacky   return cast<llvm::Constant>(GetAddrOfLocalVar(BVD));
65f22ef01cSRoman Divacky }
66f22ef01cSRoman Divacky 
67f22ef01cSRoman Divacky const llvm::Type *CodeGenFunction::ConvertTypeForMem(QualType T) {
68f22ef01cSRoman Divacky   return CGM.getTypes().ConvertTypeForMem(T);
69f22ef01cSRoman Divacky }
70f22ef01cSRoman Divacky 
71f22ef01cSRoman Divacky const llvm::Type *CodeGenFunction::ConvertType(QualType T) {
72f22ef01cSRoman Divacky   return CGM.getTypes().ConvertType(T);
73f22ef01cSRoman Divacky }
74f22ef01cSRoman Divacky 
75f22ef01cSRoman Divacky bool CodeGenFunction::hasAggregateLLVMType(QualType T) {
76f22ef01cSRoman Divacky   return T->isRecordType() || T->isArrayType() || T->isAnyComplexType() ||
77f22ef01cSRoman Divacky     T->isMemberFunctionPointerType();
78f22ef01cSRoman Divacky }
79f22ef01cSRoman Divacky 
80f22ef01cSRoman Divacky void CodeGenFunction::EmitReturnBlock() {
81f22ef01cSRoman Divacky   // For cleanliness, we try to avoid emitting the return block for
82f22ef01cSRoman Divacky   // simple cases.
83f22ef01cSRoman Divacky   llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
84f22ef01cSRoman Divacky 
85f22ef01cSRoman Divacky   if (CurBB) {
86f22ef01cSRoman Divacky     assert(!CurBB->getTerminator() && "Unexpected terminated block.");
87f22ef01cSRoman Divacky 
88f22ef01cSRoman Divacky     // We have a valid insert point, reuse it if it is empty or there are no
89f22ef01cSRoman Divacky     // explicit jumps to the return block.
90f22ef01cSRoman Divacky     if (CurBB->empty() || ReturnBlock->use_empty()) {
91f22ef01cSRoman Divacky       ReturnBlock->replaceAllUsesWith(CurBB);
92f22ef01cSRoman Divacky       delete ReturnBlock;
93f22ef01cSRoman Divacky     } else
94f22ef01cSRoman Divacky       EmitBlock(ReturnBlock);
95f22ef01cSRoman Divacky     return;
96f22ef01cSRoman Divacky   }
97f22ef01cSRoman Divacky 
98f22ef01cSRoman Divacky   // Otherwise, if the return block is the target of a single direct
99f22ef01cSRoman Divacky   // branch then we can just put the code in that block instead. This
100f22ef01cSRoman Divacky   // cleans up functions which started with a unified return block.
101f22ef01cSRoman Divacky   if (ReturnBlock->hasOneUse()) {
102f22ef01cSRoman Divacky     llvm::BranchInst *BI =
103f22ef01cSRoman Divacky       dyn_cast<llvm::BranchInst>(*ReturnBlock->use_begin());
104f22ef01cSRoman Divacky     if (BI && BI->isUnconditional() && BI->getSuccessor(0) == ReturnBlock) {
105f22ef01cSRoman Divacky       // Reset insertion point and delete the branch.
106f22ef01cSRoman Divacky       Builder.SetInsertPoint(BI->getParent());
107f22ef01cSRoman Divacky       BI->eraseFromParent();
108f22ef01cSRoman Divacky       delete ReturnBlock;
109f22ef01cSRoman Divacky       return;
110f22ef01cSRoman Divacky     }
111f22ef01cSRoman Divacky   }
112f22ef01cSRoman Divacky 
113f22ef01cSRoman Divacky   // FIXME: We are at an unreachable point, there is no reason to emit the block
114f22ef01cSRoman Divacky   // unless it has uses. However, we still need a place to put the debug
115f22ef01cSRoman Divacky   // region.end for now.
116f22ef01cSRoman Divacky 
117f22ef01cSRoman Divacky   EmitBlock(ReturnBlock);
118f22ef01cSRoman Divacky }
119f22ef01cSRoman Divacky 
120f22ef01cSRoman Divacky void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
121f22ef01cSRoman Divacky   assert(BreakContinueStack.empty() &&
122f22ef01cSRoman Divacky          "mismatched push/pop in break/continue stack!");
123f22ef01cSRoman Divacky   assert(BlockScopes.empty() &&
124f22ef01cSRoman Divacky          "did not remove all blocks from block scope map!");
125f22ef01cSRoman Divacky   assert(CleanupEntries.empty() &&
126f22ef01cSRoman Divacky          "mismatched push/pop in cleanup stack!");
127f22ef01cSRoman Divacky 
128f22ef01cSRoman Divacky   // Emit function epilog (to return).
129f22ef01cSRoman Divacky   EmitReturnBlock();
130f22ef01cSRoman Divacky 
131f22ef01cSRoman Divacky   // Emit debug descriptor for function end.
132f22ef01cSRoman Divacky   if (CGDebugInfo *DI = getDebugInfo()) {
133f22ef01cSRoman Divacky     DI->setLocation(EndLoc);
134f22ef01cSRoman Divacky     DI->EmitRegionEnd(CurFn, Builder);
135f22ef01cSRoman Divacky   }
136f22ef01cSRoman Divacky 
137f22ef01cSRoman Divacky   EmitFunctionEpilog(*CurFnInfo, ReturnValue);
138f22ef01cSRoman Divacky   EmitEndEHSpec(CurCodeDecl);
139f22ef01cSRoman Divacky 
140f22ef01cSRoman Divacky   // If someone did an indirect goto, emit the indirect goto block at the end of
141f22ef01cSRoman Divacky   // the function.
142f22ef01cSRoman Divacky   if (IndirectBranch) {
143f22ef01cSRoman Divacky     EmitBlock(IndirectBranch->getParent());
144f22ef01cSRoman Divacky     Builder.ClearInsertionPoint();
145f22ef01cSRoman Divacky   }
146f22ef01cSRoman Divacky 
147f22ef01cSRoman Divacky   // Remove the AllocaInsertPt instruction, which is just a convenience for us.
148f22ef01cSRoman Divacky   llvm::Instruction *Ptr = AllocaInsertPt;
149f22ef01cSRoman Divacky   AllocaInsertPt = 0;
150f22ef01cSRoman Divacky   Ptr->eraseFromParent();
151f22ef01cSRoman Divacky 
152f22ef01cSRoman Divacky   // If someone took the address of a label but never did an indirect goto, we
153f22ef01cSRoman Divacky   // made a zero entry PHI node, which is illegal, zap it now.
154f22ef01cSRoman Divacky   if (IndirectBranch) {
155f22ef01cSRoman Divacky     llvm::PHINode *PN = cast<llvm::PHINode>(IndirectBranch->getAddress());
156f22ef01cSRoman Divacky     if (PN->getNumIncomingValues() == 0) {
157f22ef01cSRoman Divacky       PN->replaceAllUsesWith(llvm::UndefValue::get(PN->getType()));
158f22ef01cSRoman Divacky       PN->eraseFromParent();
159f22ef01cSRoman Divacky     }
160f22ef01cSRoman Divacky   }
161f22ef01cSRoman Divacky }
162f22ef01cSRoman Divacky 
163f22ef01cSRoman Divacky void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
164f22ef01cSRoman Divacky                                     llvm::Function *Fn,
165f22ef01cSRoman Divacky                                     const FunctionArgList &Args,
166f22ef01cSRoman Divacky                                     SourceLocation StartLoc) {
167f22ef01cSRoman Divacky   const Decl *D = GD.getDecl();
168f22ef01cSRoman Divacky 
169f22ef01cSRoman Divacky   DidCallStackSave = false;
170f22ef01cSRoman Divacky   CurCodeDecl = CurFuncDecl = D;
171f22ef01cSRoman Divacky   FnRetTy = RetTy;
172f22ef01cSRoman Divacky   CurFn = Fn;
173f22ef01cSRoman Divacky   assert(CurFn->isDeclaration() && "Function already has body?");
174f22ef01cSRoman Divacky 
175f22ef01cSRoman Divacky   // Pass inline keyword to optimizer if it appears explicitly on any
176f22ef01cSRoman Divacky   // declaration.
177f22ef01cSRoman Divacky   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
178f22ef01cSRoman Divacky     for (FunctionDecl::redecl_iterator RI = FD->redecls_begin(),
179f22ef01cSRoman Divacky            RE = FD->redecls_end(); RI != RE; ++RI)
180f22ef01cSRoman Divacky       if (RI->isInlineSpecified()) {
181f22ef01cSRoman Divacky         Fn->addFnAttr(llvm::Attribute::InlineHint);
182f22ef01cSRoman Divacky         break;
183f22ef01cSRoman Divacky       }
184f22ef01cSRoman Divacky 
185f22ef01cSRoman Divacky   llvm::BasicBlock *EntryBB = createBasicBlock("entry", CurFn);
186f22ef01cSRoman Divacky 
187f22ef01cSRoman Divacky   // Create a marker to make it easy to insert allocas into the entryblock
188f22ef01cSRoman Divacky   // later.  Don't create this with the builder, because we don't want it
189f22ef01cSRoman Divacky   // folded.
190f22ef01cSRoman Divacky   llvm::Value *Undef = llvm::UndefValue::get(llvm::Type::getInt32Ty(VMContext));
191f22ef01cSRoman Divacky   AllocaInsertPt = new llvm::BitCastInst(Undef,
192f22ef01cSRoman Divacky                                          llvm::Type::getInt32Ty(VMContext), "",
193f22ef01cSRoman Divacky                                          EntryBB);
194f22ef01cSRoman Divacky   if (Builder.isNamePreserving())
195f22ef01cSRoman Divacky     AllocaInsertPt->setName("allocapt");
196f22ef01cSRoman Divacky 
197f22ef01cSRoman Divacky   ReturnBlock = createBasicBlock("return");
198f22ef01cSRoman Divacky 
199f22ef01cSRoman Divacky   Builder.SetInsertPoint(EntryBB);
200f22ef01cSRoman Divacky 
201f22ef01cSRoman Divacky   QualType FnType = getContext().getFunctionType(RetTy, 0, 0, false, 0,
202f22ef01cSRoman Divacky                                                  false, false, 0, 0,
203f22ef01cSRoman Divacky                                                  /*FIXME?*/
204f22ef01cSRoman Divacky                                                  FunctionType::ExtInfo());
205f22ef01cSRoman Divacky 
206f22ef01cSRoman Divacky   // Emit subprogram debug descriptor.
207f22ef01cSRoman Divacky   if (CGDebugInfo *DI = getDebugInfo()) {
208f22ef01cSRoman Divacky     DI->setLocation(StartLoc);
209f22ef01cSRoman Divacky     DI->EmitFunctionStart(GD, FnType, CurFn, Builder);
210f22ef01cSRoman Divacky   }
211f22ef01cSRoman Divacky 
212f22ef01cSRoman Divacky   // FIXME: Leaked.
213f22ef01cSRoman Divacky   // CC info is ignored, hopefully?
214f22ef01cSRoman Divacky   CurFnInfo = &CGM.getTypes().getFunctionInfo(FnRetTy, Args,
215f22ef01cSRoman Divacky                                               FunctionType::ExtInfo());
216f22ef01cSRoman Divacky 
217f22ef01cSRoman Divacky   if (RetTy->isVoidType()) {
218f22ef01cSRoman Divacky     // Void type; nothing to return.
219f22ef01cSRoman Divacky     ReturnValue = 0;
220f22ef01cSRoman Divacky   } else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect &&
221f22ef01cSRoman Divacky              hasAggregateLLVMType(CurFnInfo->getReturnType())) {
222f22ef01cSRoman Divacky     // Indirect aggregate return; emit returned value directly into sret slot.
223f22ef01cSRoman Divacky     // This reduces code size, and affects correctness in C++.
224f22ef01cSRoman Divacky     ReturnValue = CurFn->arg_begin();
225f22ef01cSRoman Divacky   } else {
226f22ef01cSRoman Divacky     ReturnValue = CreateIRTemp(RetTy, "retval");
227f22ef01cSRoman Divacky   }
228f22ef01cSRoman Divacky 
229f22ef01cSRoman Divacky   EmitStartEHSpec(CurCodeDecl);
230f22ef01cSRoman Divacky   EmitFunctionProlog(*CurFnInfo, CurFn, Args);
231f22ef01cSRoman Divacky 
232f22ef01cSRoman Divacky   if (CXXThisDecl)
233f22ef01cSRoman Divacky     CXXThisValue = Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this");
234f22ef01cSRoman Divacky   if (CXXVTTDecl)
235f22ef01cSRoman Divacky     CXXVTTValue = Builder.CreateLoad(LocalDeclMap[CXXVTTDecl], "vtt");
236f22ef01cSRoman Divacky 
237f22ef01cSRoman Divacky   // If any of the arguments have a variably modified type, make sure to
238f22ef01cSRoman Divacky   // emit the type size.
239f22ef01cSRoman Divacky   for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
240f22ef01cSRoman Divacky        i != e; ++i) {
241f22ef01cSRoman Divacky     QualType Ty = i->second;
242f22ef01cSRoman Divacky 
243f22ef01cSRoman Divacky     if (Ty->isVariablyModifiedType())
244f22ef01cSRoman Divacky       EmitVLASize(Ty);
245f22ef01cSRoman Divacky   }
246f22ef01cSRoman Divacky }
247f22ef01cSRoman Divacky 
248f22ef01cSRoman Divacky void CodeGenFunction::EmitFunctionBody(FunctionArgList &Args) {
249f22ef01cSRoman Divacky   const FunctionDecl *FD = cast<FunctionDecl>(CurGD.getDecl());
250f22ef01cSRoman Divacky   assert(FD->getBody());
251f22ef01cSRoman Divacky   EmitStmt(FD->getBody());
252f22ef01cSRoman Divacky }
253f22ef01cSRoman Divacky 
254f22ef01cSRoman Divacky void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn) {
255f22ef01cSRoman Divacky   const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
256f22ef01cSRoman Divacky 
257f22ef01cSRoman Divacky   // Check if we should generate debug info for this function.
258f22ef01cSRoman Divacky   if (CGM.getDebugInfo() && !FD->hasAttr<NoDebugAttr>())
259f22ef01cSRoman Divacky     DebugInfo = CGM.getDebugInfo();
260f22ef01cSRoman Divacky 
261f22ef01cSRoman Divacky   FunctionArgList Args;
262f22ef01cSRoman Divacky 
263f22ef01cSRoman Divacky   CurGD = GD;
264f22ef01cSRoman Divacky   if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
265f22ef01cSRoman Divacky     if (MD->isInstance()) {
266f22ef01cSRoman Divacky       // Create the implicit 'this' decl.
267f22ef01cSRoman Divacky       // FIXME: I'm not entirely sure I like using a fake decl just for code
268f22ef01cSRoman Divacky       // generation. Maybe we can come up with a better way?
269f22ef01cSRoman Divacky       CXXThisDecl = ImplicitParamDecl::Create(getContext(), 0,
270f22ef01cSRoman Divacky                                               FD->getLocation(),
271f22ef01cSRoman Divacky                                               &getContext().Idents.get("this"),
272f22ef01cSRoman Divacky                                               MD->getThisType(getContext()));
273f22ef01cSRoman Divacky       Args.push_back(std::make_pair(CXXThisDecl, CXXThisDecl->getType()));
274f22ef01cSRoman Divacky 
275f22ef01cSRoman Divacky       // Check if we need a VTT parameter as well.
276f22ef01cSRoman Divacky       if (CodeGenVTables::needsVTTParameter(GD)) {
277f22ef01cSRoman Divacky         // FIXME: The comment about using a fake decl above applies here too.
278f22ef01cSRoman Divacky         QualType T = getContext().getPointerType(getContext().VoidPtrTy);
279f22ef01cSRoman Divacky         CXXVTTDecl =
280f22ef01cSRoman Divacky           ImplicitParamDecl::Create(getContext(), 0, FD->getLocation(),
281f22ef01cSRoman Divacky                                     &getContext().Idents.get("vtt"), T);
282f22ef01cSRoman Divacky         Args.push_back(std::make_pair(CXXVTTDecl, CXXVTTDecl->getType()));
283f22ef01cSRoman Divacky       }
284f22ef01cSRoman Divacky     }
285f22ef01cSRoman Divacky   }
286f22ef01cSRoman Divacky 
287f22ef01cSRoman Divacky   if (FD->getNumParams()) {
288f22ef01cSRoman Divacky     const FunctionProtoType* FProto = FD->getType()->getAs<FunctionProtoType>();
289f22ef01cSRoman Divacky     assert(FProto && "Function def must have prototype!");
290f22ef01cSRoman Divacky 
291f22ef01cSRoman Divacky     for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i)
292f22ef01cSRoman Divacky       Args.push_back(std::make_pair(FD->getParamDecl(i),
293f22ef01cSRoman Divacky                                     FProto->getArgType(i)));
294f22ef01cSRoman Divacky   }
295f22ef01cSRoman Divacky 
296f22ef01cSRoman Divacky   SourceRange BodyRange;
297f22ef01cSRoman Divacky   if (Stmt *Body = FD->getBody()) BodyRange = Body->getSourceRange();
298f22ef01cSRoman Divacky 
299f22ef01cSRoman Divacky   // Emit the standard function prologue.
300f22ef01cSRoman Divacky   StartFunction(GD, FD->getResultType(), Fn, Args, BodyRange.getBegin());
301f22ef01cSRoman Divacky 
302f22ef01cSRoman Divacky   // Generate the body of the function.
303f22ef01cSRoman Divacky   if (isa<CXXDestructorDecl>(FD))
304f22ef01cSRoman Divacky     EmitDestructorBody(Args);
305f22ef01cSRoman Divacky   else if (isa<CXXConstructorDecl>(FD))
306f22ef01cSRoman Divacky     EmitConstructorBody(Args);
307f22ef01cSRoman Divacky   else
308f22ef01cSRoman Divacky     EmitFunctionBody(Args);
309f22ef01cSRoman Divacky 
310f22ef01cSRoman Divacky   // Emit the standard function epilogue.
311f22ef01cSRoman Divacky   FinishFunction(BodyRange.getEnd());
312f22ef01cSRoman Divacky 
313f22ef01cSRoman Divacky   // Destroy the 'this' declaration.
314f22ef01cSRoman Divacky   if (CXXThisDecl)
315f22ef01cSRoman Divacky     CXXThisDecl->Destroy(getContext());
316f22ef01cSRoman Divacky 
317f22ef01cSRoman Divacky   // Destroy the VTT declaration.
318f22ef01cSRoman Divacky   if (CXXVTTDecl)
319f22ef01cSRoman Divacky     CXXVTTDecl->Destroy(getContext());
320f22ef01cSRoman Divacky }
321f22ef01cSRoman Divacky 
322f22ef01cSRoman Divacky /// ContainsLabel - Return true if the statement contains a label in it.  If
323f22ef01cSRoman Divacky /// this statement is not executed normally, it not containing a label means
324f22ef01cSRoman Divacky /// that we can just remove the code.
325f22ef01cSRoman Divacky bool CodeGenFunction::ContainsLabel(const Stmt *S, bool IgnoreCaseStmts) {
326f22ef01cSRoman Divacky   // Null statement, not a label!
327f22ef01cSRoman Divacky   if (S == 0) return false;
328f22ef01cSRoman Divacky 
329f22ef01cSRoman Divacky   // If this is a label, we have to emit the code, consider something like:
330f22ef01cSRoman Divacky   // if (0) {  ...  foo:  bar(); }  goto foo;
331f22ef01cSRoman Divacky   if (isa<LabelStmt>(S))
332f22ef01cSRoman Divacky     return true;
333f22ef01cSRoman Divacky 
334f22ef01cSRoman Divacky   // If this is a case/default statement, and we haven't seen a switch, we have
335f22ef01cSRoman Divacky   // to emit the code.
336f22ef01cSRoman Divacky   if (isa<SwitchCase>(S) && !IgnoreCaseStmts)
337f22ef01cSRoman Divacky     return true;
338f22ef01cSRoman Divacky 
339f22ef01cSRoman Divacky   // If this is a switch statement, we want to ignore cases below it.
340f22ef01cSRoman Divacky   if (isa<SwitchStmt>(S))
341f22ef01cSRoman Divacky     IgnoreCaseStmts = true;
342f22ef01cSRoman Divacky 
343f22ef01cSRoman Divacky   // Scan subexpressions for verboten labels.
344f22ef01cSRoman Divacky   for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end();
345f22ef01cSRoman Divacky        I != E; ++I)
346f22ef01cSRoman Divacky     if (ContainsLabel(*I, IgnoreCaseStmts))
347f22ef01cSRoman Divacky       return true;
348f22ef01cSRoman Divacky 
349f22ef01cSRoman Divacky   return false;
350f22ef01cSRoman Divacky }
351f22ef01cSRoman Divacky 
352f22ef01cSRoman Divacky 
353f22ef01cSRoman Divacky /// ConstantFoldsToSimpleInteger - If the sepcified expression does not fold to
354f22ef01cSRoman Divacky /// a constant, or if it does but contains a label, return 0.  If it constant
355f22ef01cSRoman Divacky /// folds to 'true' and does not contain a label, return 1, if it constant folds
356f22ef01cSRoman Divacky /// to 'false' and does not contain a label, return -1.
357f22ef01cSRoman Divacky int CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond) {
358f22ef01cSRoman Divacky   // FIXME: Rename and handle conversion of other evaluatable things
359f22ef01cSRoman Divacky   // to bool.
360f22ef01cSRoman Divacky   Expr::EvalResult Result;
361f22ef01cSRoman Divacky   if (!Cond->Evaluate(Result, getContext()) || !Result.Val.isInt() ||
362f22ef01cSRoman Divacky       Result.HasSideEffects)
363f22ef01cSRoman Divacky     return 0;  // Not foldable, not integer or not fully evaluatable.
364f22ef01cSRoman Divacky 
365f22ef01cSRoman Divacky   if (CodeGenFunction::ContainsLabel(Cond))
366f22ef01cSRoman Divacky     return 0;  // Contains a label.
367f22ef01cSRoman Divacky 
368f22ef01cSRoman Divacky   return Result.Val.getInt().getBoolValue() ? 1 : -1;
369f22ef01cSRoman Divacky }
370f22ef01cSRoman Divacky 
371f22ef01cSRoman Divacky 
372f22ef01cSRoman Divacky /// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an if
373f22ef01cSRoman Divacky /// statement) to the specified blocks.  Based on the condition, this might try
374f22ef01cSRoman Divacky /// to simplify the codegen of the conditional based on the branch.
375f22ef01cSRoman Divacky ///
376f22ef01cSRoman Divacky void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond,
377f22ef01cSRoman Divacky                                            llvm::BasicBlock *TrueBlock,
378f22ef01cSRoman Divacky                                            llvm::BasicBlock *FalseBlock) {
379f22ef01cSRoman Divacky   if (const ParenExpr *PE = dyn_cast<ParenExpr>(Cond))
380f22ef01cSRoman Divacky     return EmitBranchOnBoolExpr(PE->getSubExpr(), TrueBlock, FalseBlock);
381f22ef01cSRoman Divacky 
382f22ef01cSRoman Divacky   if (const BinaryOperator *CondBOp = dyn_cast<BinaryOperator>(Cond)) {
383f22ef01cSRoman Divacky     // Handle X && Y in a condition.
384f22ef01cSRoman Divacky     if (CondBOp->getOpcode() == BinaryOperator::LAnd) {
385f22ef01cSRoman Divacky       // If we have "1 && X", simplify the code.  "0 && X" would have constant
386f22ef01cSRoman Divacky       // folded if the case was simple enough.
387f22ef01cSRoman Divacky       if (ConstantFoldsToSimpleInteger(CondBOp->getLHS()) == 1) {
388f22ef01cSRoman Divacky         // br(1 && X) -> br(X).
389f22ef01cSRoman Divacky         return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
390f22ef01cSRoman Divacky       }
391f22ef01cSRoman Divacky 
392f22ef01cSRoman Divacky       // If we have "X && 1", simplify the code to use an uncond branch.
393f22ef01cSRoman Divacky       // "X && 0" would have been constant folded to 0.
394f22ef01cSRoman Divacky       if (ConstantFoldsToSimpleInteger(CondBOp->getRHS()) == 1) {
395f22ef01cSRoman Divacky         // br(X && 1) -> br(X).
396f22ef01cSRoman Divacky         return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock);
397f22ef01cSRoman Divacky       }
398f22ef01cSRoman Divacky 
399f22ef01cSRoman Divacky       // Emit the LHS as a conditional.  If the LHS conditional is false, we
400f22ef01cSRoman Divacky       // want to jump to the FalseBlock.
401f22ef01cSRoman Divacky       llvm::BasicBlock *LHSTrue = createBasicBlock("land.lhs.true");
402f22ef01cSRoman Divacky       EmitBranchOnBoolExpr(CondBOp->getLHS(), LHSTrue, FalseBlock);
403f22ef01cSRoman Divacky       EmitBlock(LHSTrue);
404f22ef01cSRoman Divacky 
405f22ef01cSRoman Divacky       // Any temporaries created here are conditional.
406f22ef01cSRoman Divacky       BeginConditionalBranch();
407f22ef01cSRoman Divacky       EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
408f22ef01cSRoman Divacky       EndConditionalBranch();
409f22ef01cSRoman Divacky 
410f22ef01cSRoman Divacky       return;
411f22ef01cSRoman Divacky     } else if (CondBOp->getOpcode() == BinaryOperator::LOr) {
412f22ef01cSRoman Divacky       // If we have "0 || X", simplify the code.  "1 || X" would have constant
413f22ef01cSRoman Divacky       // folded if the case was simple enough.
414f22ef01cSRoman Divacky       if (ConstantFoldsToSimpleInteger(CondBOp->getLHS()) == -1) {
415f22ef01cSRoman Divacky         // br(0 || X) -> br(X).
416f22ef01cSRoman Divacky         return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
417f22ef01cSRoman Divacky       }
418f22ef01cSRoman Divacky 
419f22ef01cSRoman Divacky       // If we have "X || 0", simplify the code to use an uncond branch.
420f22ef01cSRoman Divacky       // "X || 1" would have been constant folded to 1.
421f22ef01cSRoman Divacky       if (ConstantFoldsToSimpleInteger(CondBOp->getRHS()) == -1) {
422f22ef01cSRoman Divacky         // br(X || 0) -> br(X).
423f22ef01cSRoman Divacky         return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock);
424f22ef01cSRoman Divacky       }
425f22ef01cSRoman Divacky 
426f22ef01cSRoman Divacky       // Emit the LHS as a conditional.  If the LHS conditional is true, we
427f22ef01cSRoman Divacky       // want to jump to the TrueBlock.
428f22ef01cSRoman Divacky       llvm::BasicBlock *LHSFalse = createBasicBlock("lor.lhs.false");
429f22ef01cSRoman Divacky       EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, LHSFalse);
430f22ef01cSRoman Divacky       EmitBlock(LHSFalse);
431f22ef01cSRoman Divacky 
432f22ef01cSRoman Divacky       // Any temporaries created here are conditional.
433f22ef01cSRoman Divacky       BeginConditionalBranch();
434f22ef01cSRoman Divacky       EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
435f22ef01cSRoman Divacky       EndConditionalBranch();
436f22ef01cSRoman Divacky 
437f22ef01cSRoman Divacky       return;
438f22ef01cSRoman Divacky     }
439f22ef01cSRoman Divacky   }
440f22ef01cSRoman Divacky 
441f22ef01cSRoman Divacky   if (const UnaryOperator *CondUOp = dyn_cast<UnaryOperator>(Cond)) {
442f22ef01cSRoman Divacky     // br(!x, t, f) -> br(x, f, t)
443f22ef01cSRoman Divacky     if (CondUOp->getOpcode() == UnaryOperator::LNot)
444f22ef01cSRoman Divacky       return EmitBranchOnBoolExpr(CondUOp->getSubExpr(), FalseBlock, TrueBlock);
445f22ef01cSRoman Divacky   }
446f22ef01cSRoman Divacky 
447f22ef01cSRoman Divacky   if (const ConditionalOperator *CondOp = dyn_cast<ConditionalOperator>(Cond)) {
448f22ef01cSRoman Divacky     // Handle ?: operator.
449f22ef01cSRoman Divacky 
450f22ef01cSRoman Divacky     // Just ignore GNU ?: extension.
451f22ef01cSRoman Divacky     if (CondOp->getLHS()) {
452f22ef01cSRoman Divacky       // br(c ? x : y, t, f) -> br(c, br(x, t, f), br(y, t, f))
453f22ef01cSRoman Divacky       llvm::BasicBlock *LHSBlock = createBasicBlock("cond.true");
454f22ef01cSRoman Divacky       llvm::BasicBlock *RHSBlock = createBasicBlock("cond.false");
455f22ef01cSRoman Divacky       EmitBranchOnBoolExpr(CondOp->getCond(), LHSBlock, RHSBlock);
456f22ef01cSRoman Divacky       EmitBlock(LHSBlock);
457f22ef01cSRoman Divacky       EmitBranchOnBoolExpr(CondOp->getLHS(), TrueBlock, FalseBlock);
458f22ef01cSRoman Divacky       EmitBlock(RHSBlock);
459f22ef01cSRoman Divacky       EmitBranchOnBoolExpr(CondOp->getRHS(), TrueBlock, FalseBlock);
460f22ef01cSRoman Divacky       return;
461f22ef01cSRoman Divacky     }
462f22ef01cSRoman Divacky   }
463f22ef01cSRoman Divacky 
464f22ef01cSRoman Divacky   // Emit the code with the fully general case.
465f22ef01cSRoman Divacky   llvm::Value *CondV = EvaluateExprAsBool(Cond);
466f22ef01cSRoman Divacky   Builder.CreateCondBr(CondV, TrueBlock, FalseBlock);
467f22ef01cSRoman Divacky }
468f22ef01cSRoman Divacky 
469f22ef01cSRoman Divacky /// ErrorUnsupported - Print out an error that codegen doesn't support the
470f22ef01cSRoman Divacky /// specified stmt yet.
471f22ef01cSRoman Divacky void CodeGenFunction::ErrorUnsupported(const Stmt *S, const char *Type,
472f22ef01cSRoman Divacky                                        bool OmitOnError) {
473f22ef01cSRoman Divacky   CGM.ErrorUnsupported(S, Type, OmitOnError);
474f22ef01cSRoman Divacky }
475f22ef01cSRoman Divacky 
476f22ef01cSRoman Divacky void
477f22ef01cSRoman Divacky CodeGenFunction::EmitNullInitialization(llvm::Value *DestPtr, QualType Ty) {
478f22ef01cSRoman Divacky   // If the type contains a pointer to data member we can't memset it to zero.
479f22ef01cSRoman Divacky   // Instead, create a null constant and copy it to the destination.
480f22ef01cSRoman Divacky   if (CGM.getTypes().ContainsPointerToDataMember(Ty)) {
481f22ef01cSRoman Divacky     llvm::Constant *NullConstant = CGM.EmitNullConstant(Ty);
482f22ef01cSRoman Divacky 
483f22ef01cSRoman Divacky     llvm::GlobalVariable *NullVariable =
484f22ef01cSRoman Divacky       new llvm::GlobalVariable(CGM.getModule(), NullConstant->getType(),
485f22ef01cSRoman Divacky                                /*isConstant=*/true,
486f22ef01cSRoman Divacky                                llvm::GlobalVariable::PrivateLinkage,
487f22ef01cSRoman Divacky                                NullConstant, llvm::Twine());
488f22ef01cSRoman Divacky     EmitAggregateCopy(DestPtr, NullVariable, Ty, /*isVolatile=*/false);
489f22ef01cSRoman Divacky     return;
490f22ef01cSRoman Divacky   }
491f22ef01cSRoman Divacky 
492f22ef01cSRoman Divacky 
493f22ef01cSRoman Divacky   // Ignore empty classes in C++.
494f22ef01cSRoman Divacky   if (getContext().getLangOptions().CPlusPlus) {
495f22ef01cSRoman Divacky     if (const RecordType *RT = Ty->getAs<RecordType>()) {
496f22ef01cSRoman Divacky       if (cast<CXXRecordDecl>(RT->getDecl())->isEmpty())
497f22ef01cSRoman Divacky         return;
498f22ef01cSRoman Divacky     }
499f22ef01cSRoman Divacky   }
500f22ef01cSRoman Divacky 
501f22ef01cSRoman Divacky   // Otherwise, just memset the whole thing to zero.  This is legal
502f22ef01cSRoman Divacky   // because in LLVM, all default initializers (other than the ones we just
503f22ef01cSRoman Divacky   // handled above) are guaranteed to have a bit pattern of all zeros.
504f22ef01cSRoman Divacky   const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext);
505f22ef01cSRoman Divacky   if (DestPtr->getType() != BP)
506f22ef01cSRoman Divacky     DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
507f22ef01cSRoman Divacky 
508f22ef01cSRoman Divacky   // Get size and alignment info for this aggregate.
509f22ef01cSRoman Divacky   std::pair<uint64_t, unsigned> TypeInfo = getContext().getTypeInfo(Ty);
510f22ef01cSRoman Divacky 
511f22ef01cSRoman Divacky   // Don't bother emitting a zero-byte memset.
512f22ef01cSRoman Divacky   if (TypeInfo.first == 0)
513f22ef01cSRoman Divacky     return;
514f22ef01cSRoman Divacky 
515f22ef01cSRoman Divacky   // FIXME: Handle variable sized types.
516f22ef01cSRoman Divacky   const llvm::Type *IntPtr = llvm::IntegerType::get(VMContext,
517f22ef01cSRoman Divacky                                                     LLVMPointerWidth);
518f22ef01cSRoman Divacky 
519f22ef01cSRoman Divacky   Builder.CreateCall5(CGM.getMemSetFn(BP, IntPtr), DestPtr,
520f22ef01cSRoman Divacky                  llvm::Constant::getNullValue(llvm::Type::getInt8Ty(VMContext)),
521f22ef01cSRoman Divacky                       // TypeInfo.first describes size in bits.
522f22ef01cSRoman Divacky                       llvm::ConstantInt::get(IntPtr, TypeInfo.first/8),
523f22ef01cSRoman Divacky                       llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
524f22ef01cSRoman Divacky                                              TypeInfo.second/8),
525f22ef01cSRoman Divacky                       llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext),
526f22ef01cSRoman Divacky                                              0));
527f22ef01cSRoman Divacky }
528f22ef01cSRoman Divacky 
529f22ef01cSRoman Divacky llvm::BlockAddress *CodeGenFunction::GetAddrOfLabel(const LabelStmt *L) {
530f22ef01cSRoman Divacky   // Make sure that there is a block for the indirect goto.
531f22ef01cSRoman Divacky   if (IndirectBranch == 0)
532f22ef01cSRoman Divacky     GetIndirectGotoBlock();
533f22ef01cSRoman Divacky 
534f22ef01cSRoman Divacky   llvm::BasicBlock *BB = getBasicBlockForLabel(L);
535f22ef01cSRoman Divacky 
536f22ef01cSRoman Divacky   // Make sure the indirect branch includes all of the address-taken blocks.
537f22ef01cSRoman Divacky   IndirectBranch->addDestination(BB);
538f22ef01cSRoman Divacky   return llvm::BlockAddress::get(CurFn, BB);
539f22ef01cSRoman Divacky }
540f22ef01cSRoman Divacky 
541f22ef01cSRoman Divacky llvm::BasicBlock *CodeGenFunction::GetIndirectGotoBlock() {
542f22ef01cSRoman Divacky   // If we already made the indirect branch for indirect goto, return its block.
543f22ef01cSRoman Divacky   if (IndirectBranch) return IndirectBranch->getParent();
544f22ef01cSRoman Divacky 
545f22ef01cSRoman Divacky   CGBuilderTy TmpBuilder(createBasicBlock("indirectgoto"));
546f22ef01cSRoman Divacky 
547f22ef01cSRoman Divacky   const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
548f22ef01cSRoman Divacky 
549f22ef01cSRoman Divacky   // Create the PHI node that indirect gotos will add entries to.
550f22ef01cSRoman Divacky   llvm::Value *DestVal = TmpBuilder.CreatePHI(Int8PtrTy, "indirect.goto.dest");
551f22ef01cSRoman Divacky 
552f22ef01cSRoman Divacky   // Create the indirect branch instruction.
553f22ef01cSRoman Divacky   IndirectBranch = TmpBuilder.CreateIndirectBr(DestVal);
554f22ef01cSRoman Divacky   return IndirectBranch->getParent();
555f22ef01cSRoman Divacky }
556f22ef01cSRoman Divacky 
557f22ef01cSRoman Divacky llvm::Value *CodeGenFunction::GetVLASize(const VariableArrayType *VAT) {
558f22ef01cSRoman Divacky   llvm::Value *&SizeEntry = VLASizeMap[VAT->getSizeExpr()];
559f22ef01cSRoman Divacky 
560f22ef01cSRoman Divacky   assert(SizeEntry && "Did not emit size for type");
561f22ef01cSRoman Divacky   return SizeEntry;
562f22ef01cSRoman Divacky }
563f22ef01cSRoman Divacky 
564f22ef01cSRoman Divacky llvm::Value *CodeGenFunction::EmitVLASize(QualType Ty) {
565f22ef01cSRoman Divacky   assert(Ty->isVariablyModifiedType() &&
566f22ef01cSRoman Divacky          "Must pass variably modified type to EmitVLASizes!");
567f22ef01cSRoman Divacky 
568f22ef01cSRoman Divacky   EnsureInsertPoint();
569f22ef01cSRoman Divacky 
570f22ef01cSRoman Divacky   if (const VariableArrayType *VAT = getContext().getAsVariableArrayType(Ty)) {
571f22ef01cSRoman Divacky     llvm::Value *&SizeEntry = VLASizeMap[VAT->getSizeExpr()];
572f22ef01cSRoman Divacky 
573f22ef01cSRoman Divacky     if (!SizeEntry) {
574f22ef01cSRoman Divacky       const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
575f22ef01cSRoman Divacky 
576f22ef01cSRoman Divacky       // Get the element size;
577f22ef01cSRoman Divacky       QualType ElemTy = VAT->getElementType();
578f22ef01cSRoman Divacky       llvm::Value *ElemSize;
579f22ef01cSRoman Divacky       if (ElemTy->isVariableArrayType())
580f22ef01cSRoman Divacky         ElemSize = EmitVLASize(ElemTy);
581f22ef01cSRoman Divacky       else
582f22ef01cSRoman Divacky         ElemSize = llvm::ConstantInt::get(SizeTy,
583f22ef01cSRoman Divacky             getContext().getTypeSizeInChars(ElemTy).getQuantity());
584f22ef01cSRoman Divacky 
585f22ef01cSRoman Divacky       llvm::Value *NumElements = EmitScalarExpr(VAT->getSizeExpr());
586f22ef01cSRoman Divacky       NumElements = Builder.CreateIntCast(NumElements, SizeTy, false, "tmp");
587f22ef01cSRoman Divacky 
588f22ef01cSRoman Divacky       SizeEntry = Builder.CreateMul(ElemSize, NumElements);
589f22ef01cSRoman Divacky     }
590f22ef01cSRoman Divacky 
591f22ef01cSRoman Divacky     return SizeEntry;
592f22ef01cSRoman Divacky   }
593f22ef01cSRoman Divacky 
594f22ef01cSRoman Divacky   if (const ArrayType *AT = dyn_cast<ArrayType>(Ty)) {
595f22ef01cSRoman Divacky     EmitVLASize(AT->getElementType());
596f22ef01cSRoman Divacky     return 0;
597f22ef01cSRoman Divacky   }
598f22ef01cSRoman Divacky 
599f22ef01cSRoman Divacky   const PointerType *PT = Ty->getAs<PointerType>();
600f22ef01cSRoman Divacky   assert(PT && "unknown VM type!");
601f22ef01cSRoman Divacky   EmitVLASize(PT->getPointeeType());
602f22ef01cSRoman Divacky   return 0;
603f22ef01cSRoman Divacky }
604f22ef01cSRoman Divacky 
605f22ef01cSRoman Divacky llvm::Value* CodeGenFunction::EmitVAListRef(const Expr* E) {
606f22ef01cSRoman Divacky   if (CGM.getContext().getBuiltinVaListType()->isArrayType()) {
607f22ef01cSRoman Divacky     return EmitScalarExpr(E);
608f22ef01cSRoman Divacky   }
609f22ef01cSRoman Divacky   return EmitLValue(E).getAddress();
610f22ef01cSRoman Divacky }
611f22ef01cSRoman Divacky 
612f22ef01cSRoman Divacky void CodeGenFunction::PushCleanupBlock(llvm::BasicBlock *CleanupEntryBlock,
613f22ef01cSRoman Divacky                                        llvm::BasicBlock *CleanupExitBlock,
614f22ef01cSRoman Divacky                                        llvm::BasicBlock *PreviousInvokeDest,
615f22ef01cSRoman Divacky                                        bool EHOnly) {
616f22ef01cSRoman Divacky   CleanupEntries.push_back(CleanupEntry(CleanupEntryBlock, CleanupExitBlock,
617f22ef01cSRoman Divacky                                         PreviousInvokeDest, EHOnly));
618f22ef01cSRoman Divacky }
619f22ef01cSRoman Divacky 
620f22ef01cSRoman Divacky void CodeGenFunction::EmitCleanupBlocks(size_t OldCleanupStackSize) {
621f22ef01cSRoman Divacky   assert(CleanupEntries.size() >= OldCleanupStackSize &&
622f22ef01cSRoman Divacky          "Cleanup stack mismatch!");
623f22ef01cSRoman Divacky 
624f22ef01cSRoman Divacky   while (CleanupEntries.size() > OldCleanupStackSize)
625f22ef01cSRoman Divacky     EmitCleanupBlock();
626f22ef01cSRoman Divacky }
627f22ef01cSRoman Divacky 
628f22ef01cSRoman Divacky CodeGenFunction::CleanupBlockInfo CodeGenFunction::PopCleanupBlock() {
629f22ef01cSRoman Divacky   CleanupEntry &CE = CleanupEntries.back();
630f22ef01cSRoman Divacky 
631f22ef01cSRoman Divacky   llvm::BasicBlock *CleanupEntryBlock = CE.CleanupEntryBlock;
632f22ef01cSRoman Divacky 
633f22ef01cSRoman Divacky   std::vector<llvm::BasicBlock *> Blocks;
634f22ef01cSRoman Divacky   std::swap(Blocks, CE.Blocks);
635f22ef01cSRoman Divacky 
636f22ef01cSRoman Divacky   std::vector<llvm::BranchInst *> BranchFixups;
637f22ef01cSRoman Divacky   std::swap(BranchFixups, CE.BranchFixups);
638f22ef01cSRoman Divacky 
639f22ef01cSRoman Divacky   bool EHOnly = CE.EHOnly;
640f22ef01cSRoman Divacky 
641f22ef01cSRoman Divacky   setInvokeDest(CE.PreviousInvokeDest);
642f22ef01cSRoman Divacky 
643f22ef01cSRoman Divacky   CleanupEntries.pop_back();
644f22ef01cSRoman Divacky 
645f22ef01cSRoman Divacky   // Check if any branch fixups pointed to the scope we just popped. If so,
646f22ef01cSRoman Divacky   // we can remove them.
647f22ef01cSRoman Divacky   for (size_t i = 0, e = BranchFixups.size(); i != e; ++i) {
648f22ef01cSRoman Divacky     llvm::BasicBlock *Dest = BranchFixups[i]->getSuccessor(0);
649f22ef01cSRoman Divacky     BlockScopeMap::iterator I = BlockScopes.find(Dest);
650f22ef01cSRoman Divacky 
651f22ef01cSRoman Divacky     if (I == BlockScopes.end())
652f22ef01cSRoman Divacky       continue;
653f22ef01cSRoman Divacky 
654f22ef01cSRoman Divacky     assert(I->second <= CleanupEntries.size() && "Invalid branch fixup!");
655f22ef01cSRoman Divacky 
656f22ef01cSRoman Divacky     if (I->second == CleanupEntries.size()) {
657f22ef01cSRoman Divacky       // We don't need to do this branch fixup.
658f22ef01cSRoman Divacky       BranchFixups[i] = BranchFixups.back();
659f22ef01cSRoman Divacky       BranchFixups.pop_back();
660f22ef01cSRoman Divacky       i--;
661f22ef01cSRoman Divacky       e--;
662f22ef01cSRoman Divacky       continue;
663f22ef01cSRoman Divacky     }
664f22ef01cSRoman Divacky   }
665f22ef01cSRoman Divacky 
666f22ef01cSRoman Divacky   llvm::BasicBlock *SwitchBlock = CE.CleanupExitBlock;
667f22ef01cSRoman Divacky   llvm::BasicBlock *EndBlock = 0;
668f22ef01cSRoman Divacky   if (!BranchFixups.empty()) {
669f22ef01cSRoman Divacky     if (!SwitchBlock)
670f22ef01cSRoman Divacky       SwitchBlock = createBasicBlock("cleanup.switch");
671f22ef01cSRoman Divacky     EndBlock = createBasicBlock("cleanup.end");
672f22ef01cSRoman Divacky 
673f22ef01cSRoman Divacky     llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
674f22ef01cSRoman Divacky 
675f22ef01cSRoman Divacky     Builder.SetInsertPoint(SwitchBlock);
676f22ef01cSRoman Divacky 
677f22ef01cSRoman Divacky     llvm::Value *DestCodePtr
678f22ef01cSRoman Divacky       = CreateTempAlloca(llvm::Type::getInt32Ty(VMContext),
679f22ef01cSRoman Divacky                          "cleanup.dst");
680f22ef01cSRoman Divacky     llvm::Value *DestCode = Builder.CreateLoad(DestCodePtr, "tmp");
681f22ef01cSRoman Divacky 
682f22ef01cSRoman Divacky     // Create a switch instruction to determine where to jump next.
683f22ef01cSRoman Divacky     llvm::SwitchInst *SI = Builder.CreateSwitch(DestCode, EndBlock,
684f22ef01cSRoman Divacky                                                 BranchFixups.size());
685f22ef01cSRoman Divacky 
686f22ef01cSRoman Divacky     // Restore the current basic block (if any)
687f22ef01cSRoman Divacky     if (CurBB) {
688f22ef01cSRoman Divacky       Builder.SetInsertPoint(CurBB);
689f22ef01cSRoman Divacky 
690f22ef01cSRoman Divacky       // If we had a current basic block, we also need to emit an instruction
691f22ef01cSRoman Divacky       // to initialize the cleanup destination.
692f22ef01cSRoman Divacky       Builder.CreateStore(llvm::Constant::getNullValue(llvm::Type::getInt32Ty(VMContext)),
693f22ef01cSRoman Divacky                           DestCodePtr);
694f22ef01cSRoman Divacky     } else
695f22ef01cSRoman Divacky       Builder.ClearInsertionPoint();
696f22ef01cSRoman Divacky 
697f22ef01cSRoman Divacky     for (size_t i = 0, e = BranchFixups.size(); i != e; ++i) {
698f22ef01cSRoman Divacky       llvm::BranchInst *BI = BranchFixups[i];
699f22ef01cSRoman Divacky       llvm::BasicBlock *Dest = BI->getSuccessor(0);
700f22ef01cSRoman Divacky 
701f22ef01cSRoman Divacky       // Fixup the branch instruction to point to the cleanup block.
702f22ef01cSRoman Divacky       BI->setSuccessor(0, CleanupEntryBlock);
703f22ef01cSRoman Divacky 
704f22ef01cSRoman Divacky       if (CleanupEntries.empty()) {
705f22ef01cSRoman Divacky         llvm::ConstantInt *ID;
706f22ef01cSRoman Divacky 
707f22ef01cSRoman Divacky         // Check if we already have a destination for this block.
708f22ef01cSRoman Divacky         if (Dest == SI->getDefaultDest())
709f22ef01cSRoman Divacky           ID = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0);
710f22ef01cSRoman Divacky         else {
711f22ef01cSRoman Divacky           ID = SI->findCaseDest(Dest);
712f22ef01cSRoman Divacky           if (!ID) {
713f22ef01cSRoman Divacky             // No code found, get a new unique one by using the number of
714f22ef01cSRoman Divacky             // switch successors.
715f22ef01cSRoman Divacky             ID = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
716f22ef01cSRoman Divacky                                         SI->getNumSuccessors());
717f22ef01cSRoman Divacky             SI->addCase(ID, Dest);
718f22ef01cSRoman Divacky           }
719f22ef01cSRoman Divacky         }
720f22ef01cSRoman Divacky 
721f22ef01cSRoman Divacky         // Store the jump destination before the branch instruction.
722f22ef01cSRoman Divacky         new llvm::StoreInst(ID, DestCodePtr, BI);
723f22ef01cSRoman Divacky       } else {
724f22ef01cSRoman Divacky         // We need to jump through another cleanup block. Create a pad block
725f22ef01cSRoman Divacky         // with a branch instruction that jumps to the final destination and add
726f22ef01cSRoman Divacky         // it as a branch fixup to the current cleanup scope.
727f22ef01cSRoman Divacky 
728f22ef01cSRoman Divacky         // Create the pad block.
729f22ef01cSRoman Divacky         llvm::BasicBlock *CleanupPad = createBasicBlock("cleanup.pad", CurFn);
730f22ef01cSRoman Divacky 
731f22ef01cSRoman Divacky         // Create a unique case ID.
732f22ef01cSRoman Divacky         llvm::ConstantInt *ID
733f22ef01cSRoman Divacky           = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
734f22ef01cSRoman Divacky                                    SI->getNumSuccessors());
735f22ef01cSRoman Divacky 
736f22ef01cSRoman Divacky         // Store the jump destination before the branch instruction.
737f22ef01cSRoman Divacky         new llvm::StoreInst(ID, DestCodePtr, BI);
738f22ef01cSRoman Divacky 
739f22ef01cSRoman Divacky         // Add it as the destination.
740f22ef01cSRoman Divacky         SI->addCase(ID, CleanupPad);
741f22ef01cSRoman Divacky 
742f22ef01cSRoman Divacky         // Create the branch to the final destination.
743f22ef01cSRoman Divacky         llvm::BranchInst *BI = llvm::BranchInst::Create(Dest);
744f22ef01cSRoman Divacky         CleanupPad->getInstList().push_back(BI);
745f22ef01cSRoman Divacky 
746f22ef01cSRoman Divacky         // And add it as a branch fixup.
747f22ef01cSRoman Divacky         CleanupEntries.back().BranchFixups.push_back(BI);
748f22ef01cSRoman Divacky       }
749f22ef01cSRoman Divacky     }
750f22ef01cSRoman Divacky   }
751f22ef01cSRoman Divacky 
752f22ef01cSRoman Divacky   // Remove all blocks from the block scope map.
753f22ef01cSRoman Divacky   for (size_t i = 0, e = Blocks.size(); i != e; ++i) {
754f22ef01cSRoman Divacky     assert(BlockScopes.count(Blocks[i]) &&
755f22ef01cSRoman Divacky            "Did not find block in scope map!");
756f22ef01cSRoman Divacky 
757f22ef01cSRoman Divacky     BlockScopes.erase(Blocks[i]);
758f22ef01cSRoman Divacky   }
759f22ef01cSRoman Divacky 
760f22ef01cSRoman Divacky   return CleanupBlockInfo(CleanupEntryBlock, SwitchBlock, EndBlock, EHOnly);
761f22ef01cSRoman Divacky }
762f22ef01cSRoman Divacky 
763f22ef01cSRoman Divacky void CodeGenFunction::EmitCleanupBlock() {
764f22ef01cSRoman Divacky   CleanupBlockInfo Info = PopCleanupBlock();
765f22ef01cSRoman Divacky 
766f22ef01cSRoman Divacky   if (Info.EHOnly) {
767f22ef01cSRoman Divacky     // FIXME: Add this to the exceptional edge
768f22ef01cSRoman Divacky     if (Info.CleanupBlock->getNumUses() == 0)
769f22ef01cSRoman Divacky       delete Info.CleanupBlock;
770f22ef01cSRoman Divacky     return;
771f22ef01cSRoman Divacky   }
772f22ef01cSRoman Divacky 
773f22ef01cSRoman Divacky   //  Scrub debug location info.
774f22ef01cSRoman Divacky   for (llvm::BasicBlock::iterator LBI = Info.CleanupBlock->begin(),
775f22ef01cSRoman Divacky          LBE = Info.CleanupBlock->end(); LBI != LBE; ++LBI)
776f22ef01cSRoman Divacky     Builder.SetInstDebugLocation(LBI);
777f22ef01cSRoman Divacky 
778f22ef01cSRoman Divacky   llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
779f22ef01cSRoman Divacky   if (CurBB && !CurBB->getTerminator() &&
780f22ef01cSRoman Divacky       Info.CleanupBlock->getNumUses() == 0) {
781f22ef01cSRoman Divacky     CurBB->getInstList().splice(CurBB->end(), Info.CleanupBlock->getInstList());
782f22ef01cSRoman Divacky     delete Info.CleanupBlock;
783f22ef01cSRoman Divacky   } else
784f22ef01cSRoman Divacky     EmitBlock(Info.CleanupBlock);
785f22ef01cSRoman Divacky 
786f22ef01cSRoman Divacky   if (Info.SwitchBlock)
787f22ef01cSRoman Divacky     EmitBlock(Info.SwitchBlock);
788f22ef01cSRoman Divacky   if (Info.EndBlock)
789f22ef01cSRoman Divacky     EmitBlock(Info.EndBlock);
790f22ef01cSRoman Divacky }
791f22ef01cSRoman Divacky 
792f22ef01cSRoman Divacky void CodeGenFunction::AddBranchFixup(llvm::BranchInst *BI) {
793f22ef01cSRoman Divacky   assert(!CleanupEntries.empty() &&
794f22ef01cSRoman Divacky          "Trying to add branch fixup without cleanup block!");
795f22ef01cSRoman Divacky 
796f22ef01cSRoman Divacky   // FIXME: We could be more clever here and check if there's already a branch
797f22ef01cSRoman Divacky   // fixup for this destination and recycle it.
798f22ef01cSRoman Divacky   CleanupEntries.back().BranchFixups.push_back(BI);
799f22ef01cSRoman Divacky }
800f22ef01cSRoman Divacky 
801f22ef01cSRoman Divacky void CodeGenFunction::EmitBranchThroughCleanup(llvm::BasicBlock *Dest) {
802f22ef01cSRoman Divacky   if (!HaveInsertPoint())
803f22ef01cSRoman Divacky     return;
804f22ef01cSRoman Divacky 
805f22ef01cSRoman Divacky   llvm::BranchInst* BI = Builder.CreateBr(Dest);
806f22ef01cSRoman Divacky 
807f22ef01cSRoman Divacky   Builder.ClearInsertionPoint();
808f22ef01cSRoman Divacky 
809f22ef01cSRoman Divacky   // The stack is empty, no need to do any cleanup.
810f22ef01cSRoman Divacky   if (CleanupEntries.empty())
811f22ef01cSRoman Divacky     return;
812f22ef01cSRoman Divacky 
813f22ef01cSRoman Divacky   if (!Dest->getParent()) {
814f22ef01cSRoman Divacky     // We are trying to branch to a block that hasn't been inserted yet.
815f22ef01cSRoman Divacky     AddBranchFixup(BI);
816f22ef01cSRoman Divacky     return;
817f22ef01cSRoman Divacky   }
818f22ef01cSRoman Divacky 
819f22ef01cSRoman Divacky   BlockScopeMap::iterator I = BlockScopes.find(Dest);
820f22ef01cSRoman Divacky   if (I == BlockScopes.end()) {
821f22ef01cSRoman Divacky     // We are trying to jump to a block that is outside of any cleanup scope.
822f22ef01cSRoman Divacky     AddBranchFixup(BI);
823f22ef01cSRoman Divacky     return;
824f22ef01cSRoman Divacky   }
825f22ef01cSRoman Divacky 
826f22ef01cSRoman Divacky   assert(I->second < CleanupEntries.size() &&
827f22ef01cSRoman Divacky          "Trying to branch into cleanup region");
828f22ef01cSRoman Divacky 
829f22ef01cSRoman Divacky   if (I->second == CleanupEntries.size() - 1) {
830f22ef01cSRoman Divacky     // We have a branch to a block in the same scope.
831f22ef01cSRoman Divacky     return;
832f22ef01cSRoman Divacky   }
833f22ef01cSRoman Divacky 
834f22ef01cSRoman Divacky   AddBranchFixup(BI);
835f22ef01cSRoman Divacky }
836