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"
17ffd1746dSEd Schouten #include "CGException.h"
18f22ef01cSRoman Divacky #include "clang/Basic/TargetInfo.h"
19f22ef01cSRoman Divacky #include "clang/AST/APValue.h"
20f22ef01cSRoman Divacky #include "clang/AST/ASTContext.h"
21f22ef01cSRoman Divacky #include "clang/AST/Decl.h"
22f22ef01cSRoman Divacky #include "clang/AST/DeclCXX.h"
23f22ef01cSRoman Divacky #include "clang/AST/StmtCXX.h"
24ffd1746dSEd Schouten #include "clang/Frontend/CodeGenOptions.h"
25f22ef01cSRoman Divacky #include "llvm/Target/TargetData.h"
26ffd1746dSEd Schouten #include "llvm/Intrinsics.h"
27f22ef01cSRoman Divacky using namespace clang;
28f22ef01cSRoman Divacky using namespace CodeGen;
29f22ef01cSRoman Divacky 
30f22ef01cSRoman Divacky CodeGenFunction::CodeGenFunction(CodeGenModule &cgm)
31f22ef01cSRoman Divacky   : BlockFunction(cgm, *this, Builder), CGM(cgm),
32f22ef01cSRoman Divacky     Target(CGM.getContext().Target),
33f22ef01cSRoman Divacky     Builder(cgm.getModule().getContext()),
34ffd1746dSEd Schouten     ExceptionSlot(0), DebugInfo(0), IndirectBranch(0),
35f22ef01cSRoman Divacky     SwitchInsn(0), CaseRangeBlock(0), InvokeDest(0),
36ffd1746dSEd Schouten     DidCallStackSave(false), UnreachableBlock(0),
37f22ef01cSRoman Divacky     CXXThisDecl(0), CXXThisValue(0), CXXVTTDecl(0), CXXVTTValue(0),
38ffd1746dSEd Schouten     ConditionalBranchLevel(0), TerminateLandingPad(0), TerminateHandler(0),
39ffd1746dSEd Schouten     TrapBB(0) {
40ffd1746dSEd Schouten 
41ffd1746dSEd Schouten   // Get some frequently used types.
42f22ef01cSRoman Divacky   LLVMPointerWidth = Target.getPointerWidth(0);
43ffd1746dSEd Schouten   llvm::LLVMContext &LLVMContext = CGM.getLLVMContext();
44ffd1746dSEd Schouten   IntPtrTy = llvm::IntegerType::get(LLVMContext, LLVMPointerWidth);
45ffd1746dSEd Schouten   Int32Ty  = llvm::Type::getInt32Ty(LLVMContext);
46ffd1746dSEd Schouten   Int64Ty  = llvm::Type::getInt64Ty(LLVMContext);
47ffd1746dSEd Schouten 
48f22ef01cSRoman Divacky   Exceptions = getContext().getLangOptions().Exceptions;
49f22ef01cSRoman Divacky   CatchUndefined = getContext().getLangOptions().CatchUndefined;
50f22ef01cSRoman Divacky   CGM.getMangleContext().startNewFunction();
51f22ef01cSRoman Divacky }
52f22ef01cSRoman Divacky 
53f22ef01cSRoman Divacky ASTContext &CodeGenFunction::getContext() const {
54f22ef01cSRoman Divacky   return CGM.getContext();
55f22ef01cSRoman Divacky }
56f22ef01cSRoman Divacky 
57f22ef01cSRoman Divacky 
58f22ef01cSRoman Divacky llvm::Value *CodeGenFunction::GetAddrOfLocalVar(const VarDecl *VD) {
59f22ef01cSRoman Divacky   llvm::Value *Res = LocalDeclMap[VD];
60f22ef01cSRoman Divacky   assert(Res && "Invalid argument to GetAddrOfLocalVar(), no decl!");
61f22ef01cSRoman Divacky   return Res;
62f22ef01cSRoman Divacky }
63f22ef01cSRoman Divacky 
64f22ef01cSRoman Divacky llvm::Constant *
65f22ef01cSRoman Divacky CodeGenFunction::GetAddrOfStaticLocalVar(const VarDecl *BVD) {
66f22ef01cSRoman Divacky   return cast<llvm::Constant>(GetAddrOfLocalVar(BVD));
67f22ef01cSRoman Divacky }
68f22ef01cSRoman Divacky 
69f22ef01cSRoman Divacky const llvm::Type *CodeGenFunction::ConvertTypeForMem(QualType T) {
70f22ef01cSRoman Divacky   return CGM.getTypes().ConvertTypeForMem(T);
71f22ef01cSRoman Divacky }
72f22ef01cSRoman Divacky 
73f22ef01cSRoman Divacky const llvm::Type *CodeGenFunction::ConvertType(QualType T) {
74f22ef01cSRoman Divacky   return CGM.getTypes().ConvertType(T);
75f22ef01cSRoman Divacky }
76f22ef01cSRoman Divacky 
77f22ef01cSRoman Divacky bool CodeGenFunction::hasAggregateLLVMType(QualType T) {
78f22ef01cSRoman Divacky   return T->isRecordType() || T->isArrayType() || T->isAnyComplexType() ||
79f22ef01cSRoman Divacky     T->isMemberFunctionPointerType();
80f22ef01cSRoman Divacky }
81f22ef01cSRoman Divacky 
82f22ef01cSRoman Divacky void CodeGenFunction::EmitReturnBlock() {
83f22ef01cSRoman Divacky   // For cleanliness, we try to avoid emitting the return block for
84f22ef01cSRoman Divacky   // simple cases.
85f22ef01cSRoman Divacky   llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
86f22ef01cSRoman Divacky 
87f22ef01cSRoman Divacky   if (CurBB) {
88f22ef01cSRoman Divacky     assert(!CurBB->getTerminator() && "Unexpected terminated block.");
89f22ef01cSRoman Divacky 
90f22ef01cSRoman Divacky     // We have a valid insert point, reuse it if it is empty or there are no
91f22ef01cSRoman Divacky     // explicit jumps to the return block.
92ffd1746dSEd Schouten     if (CurBB->empty() || ReturnBlock.Block->use_empty()) {
93ffd1746dSEd Schouten       ReturnBlock.Block->replaceAllUsesWith(CurBB);
94ffd1746dSEd Schouten       delete ReturnBlock.Block;
95f22ef01cSRoman Divacky     } else
96ffd1746dSEd Schouten       EmitBlock(ReturnBlock.Block);
97f22ef01cSRoman Divacky     return;
98f22ef01cSRoman Divacky   }
99f22ef01cSRoman Divacky 
100f22ef01cSRoman Divacky   // Otherwise, if the return block is the target of a single direct
101f22ef01cSRoman Divacky   // branch then we can just put the code in that block instead. This
102f22ef01cSRoman Divacky   // cleans up functions which started with a unified return block.
103ffd1746dSEd Schouten   if (ReturnBlock.Block->hasOneUse()) {
104f22ef01cSRoman Divacky     llvm::BranchInst *BI =
105ffd1746dSEd Schouten       dyn_cast<llvm::BranchInst>(*ReturnBlock.Block->use_begin());
106ffd1746dSEd Schouten     if (BI && BI->isUnconditional() &&
107ffd1746dSEd Schouten         BI->getSuccessor(0) == ReturnBlock.Block) {
108f22ef01cSRoman Divacky       // Reset insertion point and delete the branch.
109f22ef01cSRoman Divacky       Builder.SetInsertPoint(BI->getParent());
110f22ef01cSRoman Divacky       BI->eraseFromParent();
111ffd1746dSEd Schouten       delete ReturnBlock.Block;
112f22ef01cSRoman Divacky       return;
113f22ef01cSRoman Divacky     }
114f22ef01cSRoman Divacky   }
115f22ef01cSRoman Divacky 
116f22ef01cSRoman Divacky   // FIXME: We are at an unreachable point, there is no reason to emit the block
117f22ef01cSRoman Divacky   // unless it has uses. However, we still need a place to put the debug
118f22ef01cSRoman Divacky   // region.end for now.
119f22ef01cSRoman Divacky 
120ffd1746dSEd Schouten   EmitBlock(ReturnBlock.Block);
121ffd1746dSEd Schouten }
122ffd1746dSEd Schouten 
123ffd1746dSEd Schouten static void EmitIfUsed(CodeGenFunction &CGF, llvm::BasicBlock *BB) {
124ffd1746dSEd Schouten   if (!BB) return;
125ffd1746dSEd Schouten   if (!BB->use_empty())
126ffd1746dSEd Schouten     return CGF.CurFn->getBasicBlockList().push_back(BB);
127ffd1746dSEd Schouten   delete BB;
128f22ef01cSRoman Divacky }
129f22ef01cSRoman Divacky 
130f22ef01cSRoman Divacky void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
131f22ef01cSRoman Divacky   assert(BreakContinueStack.empty() &&
132f22ef01cSRoman Divacky          "mismatched push/pop in break/continue stack!");
133f22ef01cSRoman Divacky 
134f22ef01cSRoman Divacky   // Emit function epilog (to return).
135f22ef01cSRoman Divacky   EmitReturnBlock();
136f22ef01cSRoman Divacky 
137ffd1746dSEd Schouten   EmitFunctionInstrumentation("__cyg_profile_func_exit");
138ffd1746dSEd Schouten 
139f22ef01cSRoman Divacky   // Emit debug descriptor for function end.
140f22ef01cSRoman Divacky   if (CGDebugInfo *DI = getDebugInfo()) {
141f22ef01cSRoman Divacky     DI->setLocation(EndLoc);
142f22ef01cSRoman Divacky     DI->EmitRegionEnd(CurFn, Builder);
143f22ef01cSRoman Divacky   }
144f22ef01cSRoman Divacky 
145ffd1746dSEd Schouten   EmitFunctionEpilog(*CurFnInfo);
146f22ef01cSRoman Divacky   EmitEndEHSpec(CurCodeDecl);
147f22ef01cSRoman Divacky 
148ffd1746dSEd Schouten   assert(EHStack.empty() &&
149ffd1746dSEd Schouten          "did not remove all scopes from cleanup stack!");
150ffd1746dSEd Schouten 
151f22ef01cSRoman Divacky   // If someone did an indirect goto, emit the indirect goto block at the end of
152f22ef01cSRoman Divacky   // the function.
153f22ef01cSRoman Divacky   if (IndirectBranch) {
154f22ef01cSRoman Divacky     EmitBlock(IndirectBranch->getParent());
155f22ef01cSRoman Divacky     Builder.ClearInsertionPoint();
156f22ef01cSRoman Divacky   }
157f22ef01cSRoman Divacky 
158f22ef01cSRoman Divacky   // Remove the AllocaInsertPt instruction, which is just a convenience for us.
159f22ef01cSRoman Divacky   llvm::Instruction *Ptr = AllocaInsertPt;
160f22ef01cSRoman Divacky   AllocaInsertPt = 0;
161f22ef01cSRoman Divacky   Ptr->eraseFromParent();
162f22ef01cSRoman Divacky 
163f22ef01cSRoman Divacky   // If someone took the address of a label but never did an indirect goto, we
164f22ef01cSRoman Divacky   // made a zero entry PHI node, which is illegal, zap it now.
165f22ef01cSRoman Divacky   if (IndirectBranch) {
166f22ef01cSRoman Divacky     llvm::PHINode *PN = cast<llvm::PHINode>(IndirectBranch->getAddress());
167f22ef01cSRoman Divacky     if (PN->getNumIncomingValues() == 0) {
168f22ef01cSRoman Divacky       PN->replaceAllUsesWith(llvm::UndefValue::get(PN->getType()));
169f22ef01cSRoman Divacky       PN->eraseFromParent();
170f22ef01cSRoman Divacky     }
171f22ef01cSRoman Divacky   }
172ffd1746dSEd Schouten 
173ffd1746dSEd Schouten   EmitIfUsed(*this, TerminateLandingPad);
174ffd1746dSEd Schouten   EmitIfUsed(*this, TerminateHandler);
175ffd1746dSEd Schouten   EmitIfUsed(*this, UnreachableBlock);
176ffd1746dSEd Schouten 
177ffd1746dSEd Schouten   if (CGM.getCodeGenOpts().EmitDeclMetadata)
178ffd1746dSEd Schouten     EmitDeclMetadata();
179ffd1746dSEd Schouten }
180ffd1746dSEd Schouten 
181ffd1746dSEd Schouten /// ShouldInstrumentFunction - Return true if the current function should be
182ffd1746dSEd Schouten /// instrumented with __cyg_profile_func_* calls
183ffd1746dSEd Schouten bool CodeGenFunction::ShouldInstrumentFunction() {
184ffd1746dSEd Schouten   if (!CGM.getCodeGenOpts().InstrumentFunctions)
185ffd1746dSEd Schouten     return false;
186ffd1746dSEd Schouten   if (CurFuncDecl->hasAttr<NoInstrumentFunctionAttr>())
187ffd1746dSEd Schouten     return false;
188ffd1746dSEd Schouten   return true;
189ffd1746dSEd Schouten }
190ffd1746dSEd Schouten 
191ffd1746dSEd Schouten /// EmitFunctionInstrumentation - Emit LLVM code to call the specified
192ffd1746dSEd Schouten /// instrumentation function with the current function and the call site, if
193ffd1746dSEd Schouten /// function instrumentation is enabled.
194ffd1746dSEd Schouten void CodeGenFunction::EmitFunctionInstrumentation(const char *Fn) {
195ffd1746dSEd Schouten   if (!ShouldInstrumentFunction())
196ffd1746dSEd Schouten     return;
197ffd1746dSEd Schouten 
198ffd1746dSEd Schouten   const llvm::PointerType *PointerTy;
199ffd1746dSEd Schouten   const llvm::FunctionType *FunctionTy;
200ffd1746dSEd Schouten   std::vector<const llvm::Type*> ProfileFuncArgs;
201ffd1746dSEd Schouten 
202ffd1746dSEd Schouten   // void __cyg_profile_func_{enter,exit} (void *this_fn, void *call_site);
203ffd1746dSEd Schouten   PointerTy = llvm::Type::getInt8PtrTy(VMContext);
204ffd1746dSEd Schouten   ProfileFuncArgs.push_back(PointerTy);
205ffd1746dSEd Schouten   ProfileFuncArgs.push_back(PointerTy);
206ffd1746dSEd Schouten   FunctionTy = llvm::FunctionType::get(
207ffd1746dSEd Schouten     llvm::Type::getVoidTy(VMContext),
208ffd1746dSEd Schouten     ProfileFuncArgs, false);
209ffd1746dSEd Schouten 
210ffd1746dSEd Schouten   llvm::Constant *F = CGM.CreateRuntimeFunction(FunctionTy, Fn);
211ffd1746dSEd Schouten   llvm::CallInst *CallSite = Builder.CreateCall(
212ffd1746dSEd Schouten     CGM.getIntrinsic(llvm::Intrinsic::returnaddress, 0, 0),
213ffd1746dSEd Schouten     llvm::ConstantInt::get(Int32Ty, 0),
214ffd1746dSEd Schouten     "callsite");
215ffd1746dSEd Schouten 
216ffd1746dSEd Schouten   Builder.CreateCall2(F,
217ffd1746dSEd Schouten                       llvm::ConstantExpr::getBitCast(CurFn, PointerTy),
218ffd1746dSEd Schouten                       CallSite);
219f22ef01cSRoman Divacky }
220f22ef01cSRoman Divacky 
221f22ef01cSRoman Divacky void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
222f22ef01cSRoman Divacky                                     llvm::Function *Fn,
223f22ef01cSRoman Divacky                                     const FunctionArgList &Args,
224f22ef01cSRoman Divacky                                     SourceLocation StartLoc) {
225f22ef01cSRoman Divacky   const Decl *D = GD.getDecl();
226f22ef01cSRoman Divacky 
227f22ef01cSRoman Divacky   DidCallStackSave = false;
228f22ef01cSRoman Divacky   CurCodeDecl = CurFuncDecl = D;
229f22ef01cSRoman Divacky   FnRetTy = RetTy;
230f22ef01cSRoman Divacky   CurFn = Fn;
231f22ef01cSRoman Divacky   assert(CurFn->isDeclaration() && "Function already has body?");
232f22ef01cSRoman Divacky 
233f22ef01cSRoman Divacky   // Pass inline keyword to optimizer if it appears explicitly on any
234f22ef01cSRoman Divacky   // declaration.
235f22ef01cSRoman Divacky   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
236f22ef01cSRoman Divacky     for (FunctionDecl::redecl_iterator RI = FD->redecls_begin(),
237f22ef01cSRoman Divacky            RE = FD->redecls_end(); RI != RE; ++RI)
238f22ef01cSRoman Divacky       if (RI->isInlineSpecified()) {
239f22ef01cSRoman Divacky         Fn->addFnAttr(llvm::Attribute::InlineHint);
240f22ef01cSRoman Divacky         break;
241f22ef01cSRoman Divacky       }
242f22ef01cSRoman Divacky 
243f22ef01cSRoman Divacky   llvm::BasicBlock *EntryBB = createBasicBlock("entry", CurFn);
244f22ef01cSRoman Divacky 
245f22ef01cSRoman Divacky   // Create a marker to make it easy to insert allocas into the entryblock
246f22ef01cSRoman Divacky   // later.  Don't create this with the builder, because we don't want it
247f22ef01cSRoman Divacky   // folded.
248ffd1746dSEd Schouten   llvm::Value *Undef = llvm::UndefValue::get(Int32Ty);
249ffd1746dSEd Schouten   AllocaInsertPt = new llvm::BitCastInst(Undef, Int32Ty, "", EntryBB);
250f22ef01cSRoman Divacky   if (Builder.isNamePreserving())
251f22ef01cSRoman Divacky     AllocaInsertPt->setName("allocapt");
252f22ef01cSRoman Divacky 
253ffd1746dSEd Schouten   ReturnBlock = getJumpDestInCurrentScope("return");
254f22ef01cSRoman Divacky 
255f22ef01cSRoman Divacky   Builder.SetInsertPoint(EntryBB);
256f22ef01cSRoman Divacky 
257f22ef01cSRoman Divacky   QualType FnType = getContext().getFunctionType(RetTy, 0, 0, false, 0,
258f22ef01cSRoman Divacky                                                  false, false, 0, 0,
259f22ef01cSRoman Divacky                                                  /*FIXME?*/
260f22ef01cSRoman Divacky                                                  FunctionType::ExtInfo());
261f22ef01cSRoman Divacky 
262f22ef01cSRoman Divacky   // Emit subprogram debug descriptor.
263f22ef01cSRoman Divacky   if (CGDebugInfo *DI = getDebugInfo()) {
264f22ef01cSRoman Divacky     DI->setLocation(StartLoc);
265f22ef01cSRoman Divacky     DI->EmitFunctionStart(GD, FnType, CurFn, Builder);
266f22ef01cSRoman Divacky   }
267f22ef01cSRoman Divacky 
268ffd1746dSEd Schouten   EmitFunctionInstrumentation("__cyg_profile_func_enter");
269ffd1746dSEd Schouten 
270f22ef01cSRoman Divacky   // FIXME: Leaked.
271f22ef01cSRoman Divacky   // CC info is ignored, hopefully?
272f22ef01cSRoman Divacky   CurFnInfo = &CGM.getTypes().getFunctionInfo(FnRetTy, Args,
273f22ef01cSRoman Divacky                                               FunctionType::ExtInfo());
274f22ef01cSRoman Divacky 
275f22ef01cSRoman Divacky   if (RetTy->isVoidType()) {
276f22ef01cSRoman Divacky     // Void type; nothing to return.
277f22ef01cSRoman Divacky     ReturnValue = 0;
278f22ef01cSRoman Divacky   } else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect &&
279f22ef01cSRoman Divacky              hasAggregateLLVMType(CurFnInfo->getReturnType())) {
280f22ef01cSRoman Divacky     // Indirect aggregate return; emit returned value directly into sret slot.
281f22ef01cSRoman Divacky     // This reduces code size, and affects correctness in C++.
282f22ef01cSRoman Divacky     ReturnValue = CurFn->arg_begin();
283f22ef01cSRoman Divacky   } else {
284f22ef01cSRoman Divacky     ReturnValue = CreateIRTemp(RetTy, "retval");
285f22ef01cSRoman Divacky   }
286f22ef01cSRoman Divacky 
287f22ef01cSRoman Divacky   EmitStartEHSpec(CurCodeDecl);
288f22ef01cSRoman Divacky   EmitFunctionProlog(*CurFnInfo, CurFn, Args);
289f22ef01cSRoman Divacky 
290f22ef01cSRoman Divacky   if (CXXThisDecl)
291f22ef01cSRoman Divacky     CXXThisValue = Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this");
292f22ef01cSRoman Divacky   if (CXXVTTDecl)
293f22ef01cSRoman Divacky     CXXVTTValue = Builder.CreateLoad(LocalDeclMap[CXXVTTDecl], "vtt");
294f22ef01cSRoman Divacky 
295f22ef01cSRoman Divacky   // If any of the arguments have a variably modified type, make sure to
296f22ef01cSRoman Divacky   // emit the type size.
297f22ef01cSRoman Divacky   for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
298f22ef01cSRoman Divacky        i != e; ++i) {
299f22ef01cSRoman Divacky     QualType Ty = i->second;
300f22ef01cSRoman Divacky 
301f22ef01cSRoman Divacky     if (Ty->isVariablyModifiedType())
302f22ef01cSRoman Divacky       EmitVLASize(Ty);
303f22ef01cSRoman Divacky   }
304f22ef01cSRoman Divacky }
305f22ef01cSRoman Divacky 
306f22ef01cSRoman Divacky void CodeGenFunction::EmitFunctionBody(FunctionArgList &Args) {
307f22ef01cSRoman Divacky   const FunctionDecl *FD = cast<FunctionDecl>(CurGD.getDecl());
308f22ef01cSRoman Divacky   assert(FD->getBody());
309f22ef01cSRoman Divacky   EmitStmt(FD->getBody());
310f22ef01cSRoman Divacky }
311f22ef01cSRoman Divacky 
312f22ef01cSRoman Divacky void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn) {
313f22ef01cSRoman Divacky   const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
314f22ef01cSRoman Divacky 
315f22ef01cSRoman Divacky   // Check if we should generate debug info for this function.
316f22ef01cSRoman Divacky   if (CGM.getDebugInfo() && !FD->hasAttr<NoDebugAttr>())
317f22ef01cSRoman Divacky     DebugInfo = CGM.getDebugInfo();
318f22ef01cSRoman Divacky 
319f22ef01cSRoman Divacky   FunctionArgList Args;
320f22ef01cSRoman Divacky 
321f22ef01cSRoman Divacky   CurGD = GD;
322f22ef01cSRoman Divacky   if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
323f22ef01cSRoman Divacky     if (MD->isInstance()) {
324f22ef01cSRoman Divacky       // Create the implicit 'this' decl.
325f22ef01cSRoman Divacky       // FIXME: I'm not entirely sure I like using a fake decl just for code
326f22ef01cSRoman Divacky       // generation. Maybe we can come up with a better way?
327f22ef01cSRoman Divacky       CXXThisDecl = ImplicitParamDecl::Create(getContext(), 0,
328f22ef01cSRoman Divacky                                               FD->getLocation(),
329f22ef01cSRoman Divacky                                               &getContext().Idents.get("this"),
330f22ef01cSRoman Divacky                                               MD->getThisType(getContext()));
331f22ef01cSRoman Divacky       Args.push_back(std::make_pair(CXXThisDecl, CXXThisDecl->getType()));
332f22ef01cSRoman Divacky 
333f22ef01cSRoman Divacky       // Check if we need a VTT parameter as well.
334f22ef01cSRoman Divacky       if (CodeGenVTables::needsVTTParameter(GD)) {
335f22ef01cSRoman Divacky         // FIXME: The comment about using a fake decl above applies here too.
336f22ef01cSRoman Divacky         QualType T = getContext().getPointerType(getContext().VoidPtrTy);
337f22ef01cSRoman Divacky         CXXVTTDecl =
338f22ef01cSRoman Divacky           ImplicitParamDecl::Create(getContext(), 0, FD->getLocation(),
339f22ef01cSRoman Divacky                                     &getContext().Idents.get("vtt"), T);
340f22ef01cSRoman Divacky         Args.push_back(std::make_pair(CXXVTTDecl, CXXVTTDecl->getType()));
341f22ef01cSRoman Divacky       }
342f22ef01cSRoman Divacky     }
343f22ef01cSRoman Divacky   }
344f22ef01cSRoman Divacky 
345f22ef01cSRoman Divacky   if (FD->getNumParams()) {
346f22ef01cSRoman Divacky     const FunctionProtoType* FProto = FD->getType()->getAs<FunctionProtoType>();
347f22ef01cSRoman Divacky     assert(FProto && "Function def must have prototype!");
348f22ef01cSRoman Divacky 
349f22ef01cSRoman Divacky     for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i)
350f22ef01cSRoman Divacky       Args.push_back(std::make_pair(FD->getParamDecl(i),
351f22ef01cSRoman Divacky                                     FProto->getArgType(i)));
352f22ef01cSRoman Divacky   }
353f22ef01cSRoman Divacky 
354f22ef01cSRoman Divacky   SourceRange BodyRange;
355f22ef01cSRoman Divacky   if (Stmt *Body = FD->getBody()) BodyRange = Body->getSourceRange();
356f22ef01cSRoman Divacky 
357f22ef01cSRoman Divacky   // Emit the standard function prologue.
358f22ef01cSRoman Divacky   StartFunction(GD, FD->getResultType(), Fn, Args, BodyRange.getBegin());
359f22ef01cSRoman Divacky 
360f22ef01cSRoman Divacky   // Generate the body of the function.
361f22ef01cSRoman Divacky   if (isa<CXXDestructorDecl>(FD))
362f22ef01cSRoman Divacky     EmitDestructorBody(Args);
363f22ef01cSRoman Divacky   else if (isa<CXXConstructorDecl>(FD))
364f22ef01cSRoman Divacky     EmitConstructorBody(Args);
365f22ef01cSRoman Divacky   else
366f22ef01cSRoman Divacky     EmitFunctionBody(Args);
367f22ef01cSRoman Divacky 
368f22ef01cSRoman Divacky   // Emit the standard function epilogue.
369f22ef01cSRoman Divacky   FinishFunction(BodyRange.getEnd());
370f22ef01cSRoman Divacky 
371f22ef01cSRoman Divacky   // Destroy the 'this' declaration.
372f22ef01cSRoman Divacky   if (CXXThisDecl)
373f22ef01cSRoman Divacky     CXXThisDecl->Destroy(getContext());
374f22ef01cSRoman Divacky 
375f22ef01cSRoman Divacky   // Destroy the VTT declaration.
376f22ef01cSRoman Divacky   if (CXXVTTDecl)
377f22ef01cSRoman Divacky     CXXVTTDecl->Destroy(getContext());
378f22ef01cSRoman Divacky }
379f22ef01cSRoman Divacky 
380f22ef01cSRoman Divacky /// ContainsLabel - Return true if the statement contains a label in it.  If
381f22ef01cSRoman Divacky /// this statement is not executed normally, it not containing a label means
382f22ef01cSRoman Divacky /// that we can just remove the code.
383f22ef01cSRoman Divacky bool CodeGenFunction::ContainsLabel(const Stmt *S, bool IgnoreCaseStmts) {
384f22ef01cSRoman Divacky   // Null statement, not a label!
385f22ef01cSRoman Divacky   if (S == 0) return false;
386f22ef01cSRoman Divacky 
387f22ef01cSRoman Divacky   // If this is a label, we have to emit the code, consider something like:
388f22ef01cSRoman Divacky   // if (0) {  ...  foo:  bar(); }  goto foo;
389f22ef01cSRoman Divacky   if (isa<LabelStmt>(S))
390f22ef01cSRoman Divacky     return true;
391f22ef01cSRoman Divacky 
392f22ef01cSRoman Divacky   // If this is a case/default statement, and we haven't seen a switch, we have
393f22ef01cSRoman Divacky   // to emit the code.
394f22ef01cSRoman Divacky   if (isa<SwitchCase>(S) && !IgnoreCaseStmts)
395f22ef01cSRoman Divacky     return true;
396f22ef01cSRoman Divacky 
397f22ef01cSRoman Divacky   // If this is a switch statement, we want to ignore cases below it.
398f22ef01cSRoman Divacky   if (isa<SwitchStmt>(S))
399f22ef01cSRoman Divacky     IgnoreCaseStmts = true;
400f22ef01cSRoman Divacky 
401f22ef01cSRoman Divacky   // Scan subexpressions for verboten labels.
402f22ef01cSRoman Divacky   for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end();
403f22ef01cSRoman Divacky        I != E; ++I)
404f22ef01cSRoman Divacky     if (ContainsLabel(*I, IgnoreCaseStmts))
405f22ef01cSRoman Divacky       return true;
406f22ef01cSRoman Divacky 
407f22ef01cSRoman Divacky   return false;
408f22ef01cSRoman Divacky }
409f22ef01cSRoman Divacky 
410f22ef01cSRoman Divacky 
411f22ef01cSRoman Divacky /// ConstantFoldsToSimpleInteger - If the sepcified expression does not fold to
412f22ef01cSRoman Divacky /// a constant, or if it does but contains a label, return 0.  If it constant
413f22ef01cSRoman Divacky /// folds to 'true' and does not contain a label, return 1, if it constant folds
414f22ef01cSRoman Divacky /// to 'false' and does not contain a label, return -1.
415f22ef01cSRoman Divacky int CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond) {
416f22ef01cSRoman Divacky   // FIXME: Rename and handle conversion of other evaluatable things
417f22ef01cSRoman Divacky   // to bool.
418f22ef01cSRoman Divacky   Expr::EvalResult Result;
419f22ef01cSRoman Divacky   if (!Cond->Evaluate(Result, getContext()) || !Result.Val.isInt() ||
420f22ef01cSRoman Divacky       Result.HasSideEffects)
421f22ef01cSRoman Divacky     return 0;  // Not foldable, not integer or not fully evaluatable.
422f22ef01cSRoman Divacky 
423f22ef01cSRoman Divacky   if (CodeGenFunction::ContainsLabel(Cond))
424f22ef01cSRoman Divacky     return 0;  // Contains a label.
425f22ef01cSRoman Divacky 
426f22ef01cSRoman Divacky   return Result.Val.getInt().getBoolValue() ? 1 : -1;
427f22ef01cSRoman Divacky }
428f22ef01cSRoman Divacky 
429f22ef01cSRoman Divacky 
430f22ef01cSRoman Divacky /// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an if
431f22ef01cSRoman Divacky /// statement) to the specified blocks.  Based on the condition, this might try
432f22ef01cSRoman Divacky /// to simplify the codegen of the conditional based on the branch.
433f22ef01cSRoman Divacky ///
434f22ef01cSRoman Divacky void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond,
435f22ef01cSRoman Divacky                                            llvm::BasicBlock *TrueBlock,
436f22ef01cSRoman Divacky                                            llvm::BasicBlock *FalseBlock) {
437f22ef01cSRoman Divacky   if (const ParenExpr *PE = dyn_cast<ParenExpr>(Cond))
438f22ef01cSRoman Divacky     return EmitBranchOnBoolExpr(PE->getSubExpr(), TrueBlock, FalseBlock);
439f22ef01cSRoman Divacky 
440f22ef01cSRoman Divacky   if (const BinaryOperator *CondBOp = dyn_cast<BinaryOperator>(Cond)) {
441f22ef01cSRoman Divacky     // Handle X && Y in a condition.
442f22ef01cSRoman Divacky     if (CondBOp->getOpcode() == BinaryOperator::LAnd) {
443f22ef01cSRoman Divacky       // If we have "1 && X", simplify the code.  "0 && X" would have constant
444f22ef01cSRoman Divacky       // folded if the case was simple enough.
445f22ef01cSRoman Divacky       if (ConstantFoldsToSimpleInteger(CondBOp->getLHS()) == 1) {
446f22ef01cSRoman Divacky         // br(1 && X) -> br(X).
447f22ef01cSRoman Divacky         return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
448f22ef01cSRoman Divacky       }
449f22ef01cSRoman Divacky 
450f22ef01cSRoman Divacky       // If we have "X && 1", simplify the code to use an uncond branch.
451f22ef01cSRoman Divacky       // "X && 0" would have been constant folded to 0.
452f22ef01cSRoman Divacky       if (ConstantFoldsToSimpleInteger(CondBOp->getRHS()) == 1) {
453f22ef01cSRoman Divacky         // br(X && 1) -> br(X).
454f22ef01cSRoman Divacky         return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock);
455f22ef01cSRoman Divacky       }
456f22ef01cSRoman Divacky 
457f22ef01cSRoman Divacky       // Emit the LHS as a conditional.  If the LHS conditional is false, we
458f22ef01cSRoman Divacky       // want to jump to the FalseBlock.
459f22ef01cSRoman Divacky       llvm::BasicBlock *LHSTrue = createBasicBlock("land.lhs.true");
460f22ef01cSRoman Divacky       EmitBranchOnBoolExpr(CondBOp->getLHS(), LHSTrue, FalseBlock);
461f22ef01cSRoman Divacky       EmitBlock(LHSTrue);
462f22ef01cSRoman Divacky 
463f22ef01cSRoman Divacky       // Any temporaries created here are conditional.
464f22ef01cSRoman Divacky       BeginConditionalBranch();
465f22ef01cSRoman Divacky       EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
466f22ef01cSRoman Divacky       EndConditionalBranch();
467f22ef01cSRoman Divacky 
468f22ef01cSRoman Divacky       return;
469f22ef01cSRoman Divacky     } else if (CondBOp->getOpcode() == BinaryOperator::LOr) {
470f22ef01cSRoman Divacky       // If we have "0 || X", simplify the code.  "1 || X" would have constant
471f22ef01cSRoman Divacky       // folded if the case was simple enough.
472f22ef01cSRoman Divacky       if (ConstantFoldsToSimpleInteger(CondBOp->getLHS()) == -1) {
473f22ef01cSRoman Divacky         // br(0 || X) -> br(X).
474f22ef01cSRoman Divacky         return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
475f22ef01cSRoman Divacky       }
476f22ef01cSRoman Divacky 
477f22ef01cSRoman Divacky       // If we have "X || 0", simplify the code to use an uncond branch.
478f22ef01cSRoman Divacky       // "X || 1" would have been constant folded to 1.
479f22ef01cSRoman Divacky       if (ConstantFoldsToSimpleInteger(CondBOp->getRHS()) == -1) {
480f22ef01cSRoman Divacky         // br(X || 0) -> br(X).
481f22ef01cSRoman Divacky         return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock);
482f22ef01cSRoman Divacky       }
483f22ef01cSRoman Divacky 
484f22ef01cSRoman Divacky       // Emit the LHS as a conditional.  If the LHS conditional is true, we
485f22ef01cSRoman Divacky       // want to jump to the TrueBlock.
486f22ef01cSRoman Divacky       llvm::BasicBlock *LHSFalse = createBasicBlock("lor.lhs.false");
487f22ef01cSRoman Divacky       EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, LHSFalse);
488f22ef01cSRoman Divacky       EmitBlock(LHSFalse);
489f22ef01cSRoman Divacky 
490f22ef01cSRoman Divacky       // Any temporaries created here are conditional.
491f22ef01cSRoman Divacky       BeginConditionalBranch();
492f22ef01cSRoman Divacky       EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
493f22ef01cSRoman Divacky       EndConditionalBranch();
494f22ef01cSRoman Divacky 
495f22ef01cSRoman Divacky       return;
496f22ef01cSRoman Divacky     }
497f22ef01cSRoman Divacky   }
498f22ef01cSRoman Divacky 
499f22ef01cSRoman Divacky   if (const UnaryOperator *CondUOp = dyn_cast<UnaryOperator>(Cond)) {
500f22ef01cSRoman Divacky     // br(!x, t, f) -> br(x, f, t)
501f22ef01cSRoman Divacky     if (CondUOp->getOpcode() == UnaryOperator::LNot)
502f22ef01cSRoman Divacky       return EmitBranchOnBoolExpr(CondUOp->getSubExpr(), FalseBlock, TrueBlock);
503f22ef01cSRoman Divacky   }
504f22ef01cSRoman Divacky 
505f22ef01cSRoman Divacky   if (const ConditionalOperator *CondOp = dyn_cast<ConditionalOperator>(Cond)) {
506f22ef01cSRoman Divacky     // Handle ?: operator.
507f22ef01cSRoman Divacky 
508f22ef01cSRoman Divacky     // Just ignore GNU ?: extension.
509f22ef01cSRoman Divacky     if (CondOp->getLHS()) {
510f22ef01cSRoman Divacky       // br(c ? x : y, t, f) -> br(c, br(x, t, f), br(y, t, f))
511f22ef01cSRoman Divacky       llvm::BasicBlock *LHSBlock = createBasicBlock("cond.true");
512f22ef01cSRoman Divacky       llvm::BasicBlock *RHSBlock = createBasicBlock("cond.false");
513f22ef01cSRoman Divacky       EmitBranchOnBoolExpr(CondOp->getCond(), LHSBlock, RHSBlock);
514f22ef01cSRoman Divacky       EmitBlock(LHSBlock);
515f22ef01cSRoman Divacky       EmitBranchOnBoolExpr(CondOp->getLHS(), TrueBlock, FalseBlock);
516f22ef01cSRoman Divacky       EmitBlock(RHSBlock);
517f22ef01cSRoman Divacky       EmitBranchOnBoolExpr(CondOp->getRHS(), TrueBlock, FalseBlock);
518f22ef01cSRoman Divacky       return;
519f22ef01cSRoman Divacky     }
520f22ef01cSRoman Divacky   }
521f22ef01cSRoman Divacky 
522f22ef01cSRoman Divacky   // Emit the code with the fully general case.
523f22ef01cSRoman Divacky   llvm::Value *CondV = EvaluateExprAsBool(Cond);
524f22ef01cSRoman Divacky   Builder.CreateCondBr(CondV, TrueBlock, FalseBlock);
525f22ef01cSRoman Divacky }
526f22ef01cSRoman Divacky 
527f22ef01cSRoman Divacky /// ErrorUnsupported - Print out an error that codegen doesn't support the
528f22ef01cSRoman Divacky /// specified stmt yet.
529f22ef01cSRoman Divacky void CodeGenFunction::ErrorUnsupported(const Stmt *S, const char *Type,
530f22ef01cSRoman Divacky                                        bool OmitOnError) {
531f22ef01cSRoman Divacky   CGM.ErrorUnsupported(S, Type, OmitOnError);
532f22ef01cSRoman Divacky }
533f22ef01cSRoman Divacky 
534f22ef01cSRoman Divacky void
535f22ef01cSRoman Divacky CodeGenFunction::EmitNullInitialization(llvm::Value *DestPtr, QualType Ty) {
536f22ef01cSRoman Divacky   // If the type contains a pointer to data member we can't memset it to zero.
537f22ef01cSRoman Divacky   // Instead, create a null constant and copy it to the destination.
538f22ef01cSRoman Divacky   if (CGM.getTypes().ContainsPointerToDataMember(Ty)) {
539f22ef01cSRoman Divacky     llvm::Constant *NullConstant = CGM.EmitNullConstant(Ty);
540f22ef01cSRoman Divacky 
541f22ef01cSRoman Divacky     llvm::GlobalVariable *NullVariable =
542f22ef01cSRoman Divacky       new llvm::GlobalVariable(CGM.getModule(), NullConstant->getType(),
543f22ef01cSRoman Divacky                                /*isConstant=*/true,
544f22ef01cSRoman Divacky                                llvm::GlobalVariable::PrivateLinkage,
545f22ef01cSRoman Divacky                                NullConstant, llvm::Twine());
546f22ef01cSRoman Divacky     EmitAggregateCopy(DestPtr, NullVariable, Ty, /*isVolatile=*/false);
547f22ef01cSRoman Divacky     return;
548f22ef01cSRoman Divacky   }
549f22ef01cSRoman Divacky 
550f22ef01cSRoman Divacky 
551f22ef01cSRoman Divacky   // Ignore empty classes in C++.
552f22ef01cSRoman Divacky   if (getContext().getLangOptions().CPlusPlus) {
553f22ef01cSRoman Divacky     if (const RecordType *RT = Ty->getAs<RecordType>()) {
554f22ef01cSRoman Divacky       if (cast<CXXRecordDecl>(RT->getDecl())->isEmpty())
555f22ef01cSRoman Divacky         return;
556f22ef01cSRoman Divacky     }
557f22ef01cSRoman Divacky   }
558f22ef01cSRoman Divacky 
559f22ef01cSRoman Divacky   // Otherwise, just memset the whole thing to zero.  This is legal
560f22ef01cSRoman Divacky   // because in LLVM, all default initializers (other than the ones we just
561f22ef01cSRoman Divacky   // handled above) are guaranteed to have a bit pattern of all zeros.
562f22ef01cSRoman Divacky   const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext);
563f22ef01cSRoman Divacky   if (DestPtr->getType() != BP)
564f22ef01cSRoman Divacky     DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
565f22ef01cSRoman Divacky 
566f22ef01cSRoman Divacky   // Get size and alignment info for this aggregate.
567f22ef01cSRoman Divacky   std::pair<uint64_t, unsigned> TypeInfo = getContext().getTypeInfo(Ty);
568f22ef01cSRoman Divacky 
569f22ef01cSRoman Divacky   // Don't bother emitting a zero-byte memset.
570f22ef01cSRoman Divacky   if (TypeInfo.first == 0)
571f22ef01cSRoman Divacky     return;
572f22ef01cSRoman Divacky 
573f22ef01cSRoman Divacky   // FIXME: Handle variable sized types.
574ffd1746dSEd Schouten   Builder.CreateCall5(CGM.getMemSetFn(BP, IntPtrTy), DestPtr,
575f22ef01cSRoman Divacky                  llvm::Constant::getNullValue(llvm::Type::getInt8Ty(VMContext)),
576f22ef01cSRoman Divacky                       // TypeInfo.first describes size in bits.
577ffd1746dSEd Schouten                       llvm::ConstantInt::get(IntPtrTy, TypeInfo.first/8),
578ffd1746dSEd Schouten                       llvm::ConstantInt::get(Int32Ty, TypeInfo.second/8),
579f22ef01cSRoman Divacky                       llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext),
580f22ef01cSRoman Divacky                                              0));
581f22ef01cSRoman Divacky }
582f22ef01cSRoman Divacky 
583f22ef01cSRoman Divacky llvm::BlockAddress *CodeGenFunction::GetAddrOfLabel(const LabelStmt *L) {
584f22ef01cSRoman Divacky   // Make sure that there is a block for the indirect goto.
585f22ef01cSRoman Divacky   if (IndirectBranch == 0)
586f22ef01cSRoman Divacky     GetIndirectGotoBlock();
587f22ef01cSRoman Divacky 
588ffd1746dSEd Schouten   llvm::BasicBlock *BB = getJumpDestForLabel(L).Block;
589f22ef01cSRoman Divacky 
590f22ef01cSRoman Divacky   // Make sure the indirect branch includes all of the address-taken blocks.
591f22ef01cSRoman Divacky   IndirectBranch->addDestination(BB);
592f22ef01cSRoman Divacky   return llvm::BlockAddress::get(CurFn, BB);
593f22ef01cSRoman Divacky }
594f22ef01cSRoman Divacky 
595f22ef01cSRoman Divacky llvm::BasicBlock *CodeGenFunction::GetIndirectGotoBlock() {
596f22ef01cSRoman Divacky   // If we already made the indirect branch for indirect goto, return its block.
597f22ef01cSRoman Divacky   if (IndirectBranch) return IndirectBranch->getParent();
598f22ef01cSRoman Divacky 
599f22ef01cSRoman Divacky   CGBuilderTy TmpBuilder(createBasicBlock("indirectgoto"));
600f22ef01cSRoman Divacky 
601f22ef01cSRoman Divacky   const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
602f22ef01cSRoman Divacky 
603f22ef01cSRoman Divacky   // Create the PHI node that indirect gotos will add entries to.
604f22ef01cSRoman Divacky   llvm::Value *DestVal = TmpBuilder.CreatePHI(Int8PtrTy, "indirect.goto.dest");
605f22ef01cSRoman Divacky 
606f22ef01cSRoman Divacky   // Create the indirect branch instruction.
607f22ef01cSRoman Divacky   IndirectBranch = TmpBuilder.CreateIndirectBr(DestVal);
608f22ef01cSRoman Divacky   return IndirectBranch->getParent();
609f22ef01cSRoman Divacky }
610f22ef01cSRoman Divacky 
611f22ef01cSRoman Divacky llvm::Value *CodeGenFunction::GetVLASize(const VariableArrayType *VAT) {
612f22ef01cSRoman Divacky   llvm::Value *&SizeEntry = VLASizeMap[VAT->getSizeExpr()];
613f22ef01cSRoman Divacky 
614f22ef01cSRoman Divacky   assert(SizeEntry && "Did not emit size for type");
615f22ef01cSRoman Divacky   return SizeEntry;
616f22ef01cSRoman Divacky }
617f22ef01cSRoman Divacky 
618f22ef01cSRoman Divacky llvm::Value *CodeGenFunction::EmitVLASize(QualType Ty) {
619f22ef01cSRoman Divacky   assert(Ty->isVariablyModifiedType() &&
620f22ef01cSRoman Divacky          "Must pass variably modified type to EmitVLASizes!");
621f22ef01cSRoman Divacky 
622f22ef01cSRoman Divacky   EnsureInsertPoint();
623f22ef01cSRoman Divacky 
624f22ef01cSRoman Divacky   if (const VariableArrayType *VAT = getContext().getAsVariableArrayType(Ty)) {
625f22ef01cSRoman Divacky     llvm::Value *&SizeEntry = VLASizeMap[VAT->getSizeExpr()];
626f22ef01cSRoman Divacky 
627f22ef01cSRoman Divacky     if (!SizeEntry) {
628f22ef01cSRoman Divacky       const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
629f22ef01cSRoman Divacky 
630f22ef01cSRoman Divacky       // Get the element size;
631f22ef01cSRoman Divacky       QualType ElemTy = VAT->getElementType();
632f22ef01cSRoman Divacky       llvm::Value *ElemSize;
633f22ef01cSRoman Divacky       if (ElemTy->isVariableArrayType())
634f22ef01cSRoman Divacky         ElemSize = EmitVLASize(ElemTy);
635f22ef01cSRoman Divacky       else
636f22ef01cSRoman Divacky         ElemSize = llvm::ConstantInt::get(SizeTy,
637f22ef01cSRoman Divacky             getContext().getTypeSizeInChars(ElemTy).getQuantity());
638f22ef01cSRoman Divacky 
639f22ef01cSRoman Divacky       llvm::Value *NumElements = EmitScalarExpr(VAT->getSizeExpr());
640f22ef01cSRoman Divacky       NumElements = Builder.CreateIntCast(NumElements, SizeTy, false, "tmp");
641f22ef01cSRoman Divacky 
642f22ef01cSRoman Divacky       SizeEntry = Builder.CreateMul(ElemSize, NumElements);
643f22ef01cSRoman Divacky     }
644f22ef01cSRoman Divacky 
645f22ef01cSRoman Divacky     return SizeEntry;
646f22ef01cSRoman Divacky   }
647f22ef01cSRoman Divacky 
648f22ef01cSRoman Divacky   if (const ArrayType *AT = dyn_cast<ArrayType>(Ty)) {
649f22ef01cSRoman Divacky     EmitVLASize(AT->getElementType());
650f22ef01cSRoman Divacky     return 0;
651f22ef01cSRoman Divacky   }
652f22ef01cSRoman Divacky 
653f22ef01cSRoman Divacky   const PointerType *PT = Ty->getAs<PointerType>();
654f22ef01cSRoman Divacky   assert(PT && "unknown VM type!");
655f22ef01cSRoman Divacky   EmitVLASize(PT->getPointeeType());
656f22ef01cSRoman Divacky   return 0;
657f22ef01cSRoman Divacky }
658f22ef01cSRoman Divacky 
659f22ef01cSRoman Divacky llvm::Value* CodeGenFunction::EmitVAListRef(const Expr* E) {
660ffd1746dSEd Schouten   if (CGM.getContext().getBuiltinVaListType()->isArrayType())
661f22ef01cSRoman Divacky     return EmitScalarExpr(E);
662f22ef01cSRoman Divacky   return EmitLValue(E).getAddress();
663f22ef01cSRoman Divacky }
664f22ef01cSRoman Divacky 
665ffd1746dSEd Schouten /// Pops cleanup blocks until the given savepoint is reached.
666ffd1746dSEd Schouten void CodeGenFunction::PopCleanupBlocks(EHScopeStack::stable_iterator Old) {
667ffd1746dSEd Schouten   assert(Old.isValid());
668ffd1746dSEd Schouten 
669ffd1746dSEd Schouten   EHScopeStack::iterator E = EHStack.find(Old);
670ffd1746dSEd Schouten   while (EHStack.begin() != E)
671ffd1746dSEd Schouten     PopCleanupBlock();
672f22ef01cSRoman Divacky }
673f22ef01cSRoman Divacky 
674ffd1746dSEd Schouten /// Destroys a cleanup if it was unused.
675ffd1746dSEd Schouten static void DestroyCleanup(CodeGenFunction &CGF,
676ffd1746dSEd Schouten                            llvm::BasicBlock *Entry,
677ffd1746dSEd Schouten                            llvm::BasicBlock *Exit) {
678ffd1746dSEd Schouten   assert(Entry->use_empty() && "destroying cleanup with uses!");
679ffd1746dSEd Schouten   assert(Exit->getTerminator() == 0 &&
680ffd1746dSEd Schouten          "exit has terminator but entry has no predecessors!");
681f22ef01cSRoman Divacky 
682ffd1746dSEd Schouten   // This doesn't always remove the entire cleanup, but it's much
683ffd1746dSEd Schouten   // safer as long as we don't know what blocks belong to the cleanup.
684ffd1746dSEd Schouten   // A *much* better approach if we care about this inefficiency would
685ffd1746dSEd Schouten   // be to lazily emit the cleanup.
686ffd1746dSEd Schouten 
687ffd1746dSEd Schouten   // If the exit block is distinct from the entry, give it a branch to
688ffd1746dSEd Schouten   // an unreachable destination.  This preserves the well-formedness
689ffd1746dSEd Schouten   // of the IR.
690ffd1746dSEd Schouten   if (Entry != Exit)
691ffd1746dSEd Schouten     llvm::BranchInst::Create(CGF.getUnreachableBlock(), Exit);
692ffd1746dSEd Schouten 
693ffd1746dSEd Schouten   assert(!Entry->getParent() && "cleanup entry already positioned?");
694ffd1746dSEd Schouten   // We can't just delete the entry; we have to kill any references to
695ffd1746dSEd Schouten   // its instructions in other blocks.
696ffd1746dSEd Schouten   for (llvm::BasicBlock::iterator I = Entry->begin(), E = Entry->end();
697ffd1746dSEd Schouten          I != E; ++I)
698ffd1746dSEd Schouten     if (!I->use_empty())
699ffd1746dSEd Schouten       I->replaceAllUsesWith(llvm::UndefValue::get(I->getType()));
700ffd1746dSEd Schouten   delete Entry;
701f22ef01cSRoman Divacky }
702f22ef01cSRoman Divacky 
703ffd1746dSEd Schouten /// Creates a switch instruction to thread branches out of the given
704ffd1746dSEd Schouten /// block (which is the exit block of a cleanup).
705ffd1746dSEd Schouten static void CreateCleanupSwitch(CodeGenFunction &CGF,
706ffd1746dSEd Schouten                                 llvm::BasicBlock *Block) {
707ffd1746dSEd Schouten   if (Block->getTerminator()) {
708ffd1746dSEd Schouten     assert(isa<llvm::SwitchInst>(Block->getTerminator()) &&
709ffd1746dSEd Schouten            "cleanup block already has a terminator, but it isn't a switch");
710ffd1746dSEd Schouten     return;
711f22ef01cSRoman Divacky   }
712f22ef01cSRoman Divacky 
713f22ef01cSRoman Divacky   llvm::Value *DestCodePtr
714ffd1746dSEd Schouten     = CGF.CreateTempAlloca(CGF.Builder.getInt32Ty(), "cleanup.dst");
715ffd1746dSEd Schouten   CGBuilderTy Builder(Block);
716f22ef01cSRoman Divacky   llvm::Value *DestCode = Builder.CreateLoad(DestCodePtr, "tmp");
717f22ef01cSRoman Divacky 
718f22ef01cSRoman Divacky   // Create a switch instruction to determine where to jump next.
719ffd1746dSEd Schouten   Builder.CreateSwitch(DestCode, CGF.getUnreachableBlock());
720f22ef01cSRoman Divacky }
721f22ef01cSRoman Divacky 
722ffd1746dSEd Schouten /// Attempts to reduce a cleanup's entry block to a fallthrough.  This
723ffd1746dSEd Schouten /// is basically llvm::MergeBlockIntoPredecessor, except
724ffd1746dSEd Schouten /// simplified/optimized for the tighter constraints on cleanup
725ffd1746dSEd Schouten /// blocks.
726ffd1746dSEd Schouten static void SimplifyCleanupEntry(CodeGenFunction &CGF,
727ffd1746dSEd Schouten                                  llvm::BasicBlock *Entry) {
728ffd1746dSEd Schouten   llvm::BasicBlock *Pred = Entry->getSinglePredecessor();
729ffd1746dSEd Schouten   if (!Pred) return;
730f22ef01cSRoman Divacky 
731ffd1746dSEd Schouten   llvm::BranchInst *Br = dyn_cast<llvm::BranchInst>(Pred->getTerminator());
732ffd1746dSEd Schouten   if (!Br || Br->isConditional()) return;
733ffd1746dSEd Schouten   assert(Br->getSuccessor(0) == Entry);
734f22ef01cSRoman Divacky 
735ffd1746dSEd Schouten   // If we were previously inserting at the end of the cleanup entry
736ffd1746dSEd Schouten   // block, we'll need to continue inserting at the end of the
737ffd1746dSEd Schouten   // predecessor.
738ffd1746dSEd Schouten   bool WasInsertBlock = CGF.Builder.GetInsertBlock() == Entry;
739ffd1746dSEd Schouten   assert(!WasInsertBlock || CGF.Builder.GetInsertPoint() == Entry->end());
740f22ef01cSRoman Divacky 
741ffd1746dSEd Schouten   // Kill the branch.
742ffd1746dSEd Schouten   Br->eraseFromParent();
743f22ef01cSRoman Divacky 
744ffd1746dSEd Schouten   // Merge the blocks.
745ffd1746dSEd Schouten   Pred->getInstList().splice(Pred->end(), Entry->getInstList());
746f22ef01cSRoman Divacky 
747ffd1746dSEd Schouten   // Kill the entry block.
748ffd1746dSEd Schouten   Entry->eraseFromParent();
749f22ef01cSRoman Divacky 
750ffd1746dSEd Schouten   if (WasInsertBlock)
751ffd1746dSEd Schouten     CGF.Builder.SetInsertPoint(Pred);
752f22ef01cSRoman Divacky }
753f22ef01cSRoman Divacky 
754ffd1746dSEd Schouten /// Attempts to reduce an cleanup's exit switch to an unconditional
755ffd1746dSEd Schouten /// branch.
756ffd1746dSEd Schouten static void SimplifyCleanupExit(llvm::BasicBlock *Exit) {
757ffd1746dSEd Schouten   llvm::TerminatorInst *Terminator = Exit->getTerminator();
758ffd1746dSEd Schouten   assert(Terminator && "completed cleanup exit has no terminator");
759f22ef01cSRoman Divacky 
760ffd1746dSEd Schouten   llvm::SwitchInst *Switch = dyn_cast<llvm::SwitchInst>(Terminator);
761ffd1746dSEd Schouten   if (!Switch) return;
762ffd1746dSEd Schouten   if (Switch->getNumCases() != 2) return; // default + 1
763ffd1746dSEd Schouten 
764ffd1746dSEd Schouten   llvm::LoadInst *Cond = cast<llvm::LoadInst>(Switch->getCondition());
765ffd1746dSEd Schouten   llvm::AllocaInst *CondVar = cast<llvm::AllocaInst>(Cond->getPointerOperand());
766ffd1746dSEd Schouten 
767ffd1746dSEd Schouten   // Replace the switch instruction with an unconditional branch.
768ffd1746dSEd Schouten   llvm::BasicBlock *Dest = Switch->getSuccessor(1); // default is 0
769ffd1746dSEd Schouten   Switch->eraseFromParent();
770ffd1746dSEd Schouten   llvm::BranchInst::Create(Dest, Exit);
771ffd1746dSEd Schouten 
772ffd1746dSEd Schouten   // Delete all uses of the condition variable.
773ffd1746dSEd Schouten   Cond->eraseFromParent();
774ffd1746dSEd Schouten   while (!CondVar->use_empty())
775ffd1746dSEd Schouten     cast<llvm::StoreInst>(*CondVar->use_begin())->eraseFromParent();
776ffd1746dSEd Schouten 
777ffd1746dSEd Schouten   // Delete the condition variable itself.
778ffd1746dSEd Schouten   CondVar->eraseFromParent();
779f22ef01cSRoman Divacky }
780f22ef01cSRoman Divacky 
781ffd1746dSEd Schouten /// Threads a branch fixup through a cleanup block.
782ffd1746dSEd Schouten static void ThreadFixupThroughCleanup(CodeGenFunction &CGF,
783ffd1746dSEd Schouten                                       BranchFixup &Fixup,
784ffd1746dSEd Schouten                                       llvm::BasicBlock *Entry,
785ffd1746dSEd Schouten                                       llvm::BasicBlock *Exit) {
786ffd1746dSEd Schouten   if (!Exit->getTerminator())
787ffd1746dSEd Schouten     CreateCleanupSwitch(CGF, Exit);
788ffd1746dSEd Schouten 
789ffd1746dSEd Schouten   // Find the switch and its destination index alloca.
790ffd1746dSEd Schouten   llvm::SwitchInst *Switch = cast<llvm::SwitchInst>(Exit->getTerminator());
791ffd1746dSEd Schouten   llvm::Value *DestCodePtr =
792ffd1746dSEd Schouten     cast<llvm::LoadInst>(Switch->getCondition())->getPointerOperand();
793ffd1746dSEd Schouten 
794ffd1746dSEd Schouten   // Compute the index of the new case we're adding to the switch.
795ffd1746dSEd Schouten   unsigned Index = Switch->getNumCases();
796ffd1746dSEd Schouten 
797ffd1746dSEd Schouten   const llvm::IntegerType *i32 = llvm::Type::getInt32Ty(CGF.getLLVMContext());
798ffd1746dSEd Schouten   llvm::ConstantInt *IndexV = llvm::ConstantInt::get(i32, Index);
799ffd1746dSEd Schouten 
800ffd1746dSEd Schouten   // Set the index in the origin block.
801ffd1746dSEd Schouten   new llvm::StoreInst(IndexV, DestCodePtr, Fixup.Origin);
802ffd1746dSEd Schouten 
803ffd1746dSEd Schouten   // Add a case to the switch.
804ffd1746dSEd Schouten   Switch->addCase(IndexV, Fixup.Destination);
805ffd1746dSEd Schouten 
806ffd1746dSEd Schouten   // Change the last branch to point to the cleanup entry block.
807ffd1746dSEd Schouten   Fixup.LatestBranch->setSuccessor(Fixup.LatestBranchIndex, Entry);
808ffd1746dSEd Schouten 
809ffd1746dSEd Schouten   // And finally, update the fixup.
810ffd1746dSEd Schouten   Fixup.LatestBranch = Switch;
811ffd1746dSEd Schouten   Fixup.LatestBranchIndex = Index;
812f22ef01cSRoman Divacky }
813f22ef01cSRoman Divacky 
814ffd1746dSEd Schouten /// Try to simplify both the entry and exit edges of a cleanup.
815ffd1746dSEd Schouten static void SimplifyCleanupEdges(CodeGenFunction &CGF,
816ffd1746dSEd Schouten                                  llvm::BasicBlock *Entry,
817ffd1746dSEd Schouten                                  llvm::BasicBlock *Exit) {
818f22ef01cSRoman Divacky 
819ffd1746dSEd Schouten   // Given their current implementations, it's important to run these
820ffd1746dSEd Schouten   // in this order: SimplifyCleanupEntry will delete Entry if it can
821ffd1746dSEd Schouten   // be merged into its predecessor, which will then break
822ffd1746dSEd Schouten   // SimplifyCleanupExit if (as is common) Entry == Exit.
823ffd1746dSEd Schouten 
824ffd1746dSEd Schouten   SimplifyCleanupExit(Exit);
825ffd1746dSEd Schouten   SimplifyCleanupEntry(CGF, Entry);
826ffd1746dSEd Schouten }
827ffd1746dSEd Schouten 
828ffd1746dSEd Schouten static void EmitLazyCleanup(CodeGenFunction &CGF,
829ffd1746dSEd Schouten                             EHScopeStack::LazyCleanup *Fn,
830ffd1746dSEd Schouten                             bool ForEH) {
831ffd1746dSEd Schouten   if (ForEH) CGF.EHStack.pushTerminate();
832ffd1746dSEd Schouten   Fn->Emit(CGF, ForEH);
833ffd1746dSEd Schouten   if (ForEH) CGF.EHStack.popTerminate();
834ffd1746dSEd Schouten   assert(CGF.HaveInsertPoint() && "cleanup ended with no insertion point?");
835ffd1746dSEd Schouten }
836ffd1746dSEd Schouten 
837ffd1746dSEd Schouten static void SplitAndEmitLazyCleanup(CodeGenFunction &CGF,
838ffd1746dSEd Schouten                                     EHScopeStack::LazyCleanup *Fn,
839ffd1746dSEd Schouten                                     bool ForEH,
840ffd1746dSEd Schouten                                     llvm::BasicBlock *Entry) {
841ffd1746dSEd Schouten   assert(Entry && "no entry block for cleanup");
842ffd1746dSEd Schouten 
843ffd1746dSEd Schouten   // Remove the switch and load from the end of the entry block.
844ffd1746dSEd Schouten   llvm::Instruction *Switch = &Entry->getInstList().back();
845ffd1746dSEd Schouten   Entry->getInstList().remove(Switch);
846ffd1746dSEd Schouten   assert(isa<llvm::SwitchInst>(Switch));
847ffd1746dSEd Schouten   llvm::Instruction *Load = &Entry->getInstList().back();
848ffd1746dSEd Schouten   Entry->getInstList().remove(Load);
849ffd1746dSEd Schouten   assert(isa<llvm::LoadInst>(Load));
850ffd1746dSEd Schouten 
851ffd1746dSEd Schouten   assert(Entry->getInstList().empty() &&
852ffd1746dSEd Schouten          "lazy cleanup block not empty after removing load/switch pair?");
853ffd1746dSEd Schouten 
854ffd1746dSEd Schouten   // Emit the actual cleanup at the end of the entry block.
855ffd1746dSEd Schouten   CGF.Builder.SetInsertPoint(Entry);
856ffd1746dSEd Schouten   EmitLazyCleanup(CGF, Fn, ForEH);
857ffd1746dSEd Schouten 
858ffd1746dSEd Schouten   // Put the load and switch at the end of the exit block.
859ffd1746dSEd Schouten   llvm::BasicBlock *Exit = CGF.Builder.GetInsertBlock();
860ffd1746dSEd Schouten   Exit->getInstList().push_back(Load);
861ffd1746dSEd Schouten   Exit->getInstList().push_back(Switch);
862ffd1746dSEd Schouten 
863ffd1746dSEd Schouten   // Clean up the edges if possible.
864ffd1746dSEd Schouten   SimplifyCleanupEdges(CGF, Entry, Exit);
865ffd1746dSEd Schouten 
866ffd1746dSEd Schouten   CGF.Builder.ClearInsertionPoint();
867ffd1746dSEd Schouten }
868ffd1746dSEd Schouten 
869ffd1746dSEd Schouten static void PopLazyCleanupBlock(CodeGenFunction &CGF) {
870ffd1746dSEd Schouten   assert(isa<EHLazyCleanupScope>(*CGF.EHStack.begin()) && "top not a cleanup!");
871ffd1746dSEd Schouten   EHLazyCleanupScope &Scope = cast<EHLazyCleanupScope>(*CGF.EHStack.begin());
872ffd1746dSEd Schouten   assert(Scope.getFixupDepth() <= CGF.EHStack.getNumBranchFixups());
873ffd1746dSEd Schouten 
874ffd1746dSEd Schouten   // Check whether we need an EH cleanup.  This is only true if we've
875ffd1746dSEd Schouten   // generated a lazy EH cleanup block.
876ffd1746dSEd Schouten   llvm::BasicBlock *EHEntry = Scope.getEHBlock();
877ffd1746dSEd Schouten   bool RequiresEHCleanup = (EHEntry != 0);
878ffd1746dSEd Schouten 
879ffd1746dSEd Schouten   // Check the three conditions which might require a normal cleanup:
880ffd1746dSEd Schouten 
881ffd1746dSEd Schouten   // - whether there are branch fix-ups through this cleanup
882ffd1746dSEd Schouten   unsigned FixupDepth = Scope.getFixupDepth();
883ffd1746dSEd Schouten   bool HasFixups = CGF.EHStack.getNumBranchFixups() != FixupDepth;
884ffd1746dSEd Schouten 
885ffd1746dSEd Schouten   // - whether control has already been threaded through this cleanup
886ffd1746dSEd Schouten   llvm::BasicBlock *NormalEntry = Scope.getNormalBlock();
887ffd1746dSEd Schouten   bool HasExistingBranches = (NormalEntry != 0);
888ffd1746dSEd Schouten 
889ffd1746dSEd Schouten   // - whether there's a fallthrough
890ffd1746dSEd Schouten   llvm::BasicBlock *FallthroughSource = CGF.Builder.GetInsertBlock();
891ffd1746dSEd Schouten   bool HasFallthrough = (FallthroughSource != 0);
892ffd1746dSEd Schouten 
893ffd1746dSEd Schouten   bool RequiresNormalCleanup = false;
894ffd1746dSEd Schouten   if (Scope.isNormalCleanup() &&
895ffd1746dSEd Schouten       (HasFixups || HasExistingBranches || HasFallthrough)) {
896ffd1746dSEd Schouten     RequiresNormalCleanup = true;
897ffd1746dSEd Schouten   }
898ffd1746dSEd Schouten 
899ffd1746dSEd Schouten   // If we don't need the cleanup at all, we're done.
900ffd1746dSEd Schouten   if (!RequiresNormalCleanup && !RequiresEHCleanup) {
901ffd1746dSEd Schouten     CGF.EHStack.popCleanup();
902ffd1746dSEd Schouten     assert(CGF.EHStack.getNumBranchFixups() == 0 ||
903ffd1746dSEd Schouten            CGF.EHStack.hasNormalCleanups());
904f22ef01cSRoman Divacky     return;
905f22ef01cSRoman Divacky   }
906f22ef01cSRoman Divacky 
907ffd1746dSEd Schouten   // Copy the cleanup emission data out.  Note that SmallVector
908ffd1746dSEd Schouten   // guarantees maximal alignment for its buffer regardless of its
909ffd1746dSEd Schouten   // type parameter.
910ffd1746dSEd Schouten   llvm::SmallVector<char, 8*sizeof(void*)> CleanupBuffer;
911ffd1746dSEd Schouten   CleanupBuffer.reserve(Scope.getCleanupSize());
912ffd1746dSEd Schouten   memcpy(CleanupBuffer.data(),
913ffd1746dSEd Schouten          Scope.getCleanupBuffer(), Scope.getCleanupSize());
914ffd1746dSEd Schouten   CleanupBuffer.set_size(Scope.getCleanupSize());
915ffd1746dSEd Schouten   EHScopeStack::LazyCleanup *Fn =
916ffd1746dSEd Schouten     reinterpret_cast<EHScopeStack::LazyCleanup*>(CleanupBuffer.data());
917f22ef01cSRoman Divacky 
918ffd1746dSEd Schouten   // We're done with the scope; pop it off so we can emit the cleanups.
919ffd1746dSEd Schouten   CGF.EHStack.popCleanup();
920f22ef01cSRoman Divacky 
921ffd1746dSEd Schouten   if (RequiresNormalCleanup) {
922ffd1746dSEd Schouten     // If we have a fallthrough and no other need for the cleanup,
923ffd1746dSEd Schouten     // emit it directly.
924ffd1746dSEd Schouten     if (HasFallthrough && !HasFixups && !HasExistingBranches) {
925ffd1746dSEd Schouten       EmitLazyCleanup(CGF, Fn, /*ForEH*/ false);
926ffd1746dSEd Schouten 
927ffd1746dSEd Schouten     // Otherwise, the best approach is to thread everything through
928ffd1746dSEd Schouten     // the cleanup block and then try to clean up after ourselves.
929ffd1746dSEd Schouten     } else {
930ffd1746dSEd Schouten       // Force the entry block to exist.
931ffd1746dSEd Schouten       if (!HasExistingBranches) {
932ffd1746dSEd Schouten         NormalEntry = CGF.createBasicBlock("cleanup");
933ffd1746dSEd Schouten         CreateCleanupSwitch(CGF, NormalEntry);
934f22ef01cSRoman Divacky       }
935f22ef01cSRoman Divacky 
936ffd1746dSEd Schouten       CGF.EmitBlock(NormalEntry);
937f22ef01cSRoman Divacky 
938ffd1746dSEd Schouten       // Thread the fallthrough edge through the (momentarily trivial)
939ffd1746dSEd Schouten       // cleanup.
940ffd1746dSEd Schouten       llvm::BasicBlock *FallthroughDestination = 0;
941ffd1746dSEd Schouten       if (HasFallthrough) {
942ffd1746dSEd Schouten         assert(isa<llvm::BranchInst>(FallthroughSource->getTerminator()));
943ffd1746dSEd Schouten         FallthroughDestination = CGF.createBasicBlock("cleanup.cont");
944ffd1746dSEd Schouten 
945ffd1746dSEd Schouten         BranchFixup Fix;
946ffd1746dSEd Schouten         Fix.Destination = FallthroughDestination;
947ffd1746dSEd Schouten         Fix.LatestBranch = FallthroughSource->getTerminator();
948ffd1746dSEd Schouten         Fix.LatestBranchIndex = 0;
949ffd1746dSEd Schouten         Fix.Origin = Fix.LatestBranch;
950ffd1746dSEd Schouten 
951ffd1746dSEd Schouten         // Restore fixup invariant.  EmitBlock added a branch to the
952ffd1746dSEd Schouten         // cleanup which we need to redirect to the destination.
953ffd1746dSEd Schouten         cast<llvm::BranchInst>(Fix.LatestBranch)
954ffd1746dSEd Schouten           ->setSuccessor(0, Fix.Destination);
955ffd1746dSEd Schouten 
956ffd1746dSEd Schouten         ThreadFixupThroughCleanup(CGF, Fix, NormalEntry, NormalEntry);
957f22ef01cSRoman Divacky       }
958f22ef01cSRoman Divacky 
959ffd1746dSEd Schouten       // Thread any "real" fixups we need to thread.
960ffd1746dSEd Schouten       for (unsigned I = FixupDepth, E = CGF.EHStack.getNumBranchFixups();
961ffd1746dSEd Schouten            I != E; ++I)
962ffd1746dSEd Schouten         if (CGF.EHStack.getBranchFixup(I).Destination)
963ffd1746dSEd Schouten           ThreadFixupThroughCleanup(CGF, CGF.EHStack.getBranchFixup(I),
964ffd1746dSEd Schouten                                     NormalEntry, NormalEntry);
965ffd1746dSEd Schouten 
966ffd1746dSEd Schouten       SplitAndEmitLazyCleanup(CGF, Fn, /*ForEH*/ false, NormalEntry);
967ffd1746dSEd Schouten 
968ffd1746dSEd Schouten       if (HasFallthrough)
969ffd1746dSEd Schouten         CGF.EmitBlock(FallthroughDestination);
970ffd1746dSEd Schouten     }
971ffd1746dSEd Schouten   }
972ffd1746dSEd Schouten 
973ffd1746dSEd Schouten   // Emit the EH cleanup if required.
974ffd1746dSEd Schouten   if (RequiresEHCleanup) {
975ffd1746dSEd Schouten     CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
976ffd1746dSEd Schouten     CGF.EmitBlock(EHEntry);
977ffd1746dSEd Schouten     SplitAndEmitLazyCleanup(CGF, Fn, /*ForEH*/ true, EHEntry);
978ffd1746dSEd Schouten     CGF.Builder.restoreIP(SavedIP);
979ffd1746dSEd Schouten   }
980ffd1746dSEd Schouten }
981ffd1746dSEd Schouten 
982ffd1746dSEd Schouten /// Pops a cleanup block.  If the block includes a normal cleanup, the
983ffd1746dSEd Schouten /// current insertion point is threaded through the cleanup, as are
984ffd1746dSEd Schouten /// any branch fixups on the cleanup.
985ffd1746dSEd Schouten void CodeGenFunction::PopCleanupBlock() {
986ffd1746dSEd Schouten   assert(!EHStack.empty() && "cleanup stack is empty!");
987ffd1746dSEd Schouten   if (isa<EHLazyCleanupScope>(*EHStack.begin()))
988ffd1746dSEd Schouten     return PopLazyCleanupBlock(*this);
989ffd1746dSEd Schouten 
990ffd1746dSEd Schouten   assert(isa<EHCleanupScope>(*EHStack.begin()) && "top not a cleanup!");
991ffd1746dSEd Schouten   EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.begin());
992ffd1746dSEd Schouten   assert(Scope.getFixupDepth() <= EHStack.getNumBranchFixups());
993ffd1746dSEd Schouten 
994ffd1746dSEd Schouten   // Handle the EH cleanup if (1) there is one and (2) it's different
995ffd1746dSEd Schouten   // from the normal cleanup.
996ffd1746dSEd Schouten   if (Scope.isEHCleanup() &&
997ffd1746dSEd Schouten       Scope.getEHEntry() != Scope.getNormalEntry()) {
998ffd1746dSEd Schouten     llvm::BasicBlock *EHEntry = Scope.getEHEntry();
999ffd1746dSEd Schouten     llvm::BasicBlock *EHExit = Scope.getEHExit();
1000ffd1746dSEd Schouten 
1001ffd1746dSEd Schouten     if (EHEntry->use_empty()) {
1002ffd1746dSEd Schouten       DestroyCleanup(*this, EHEntry, EHExit);
1003ffd1746dSEd Schouten     } else {
1004ffd1746dSEd Schouten       // TODO: this isn't really the ideal location to put this EH
1005ffd1746dSEd Schouten       // cleanup, but lazy emission is a better solution than trying
1006ffd1746dSEd Schouten       // to pick a better spot.
1007ffd1746dSEd Schouten       CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1008ffd1746dSEd Schouten       EmitBlock(EHEntry);
1009ffd1746dSEd Schouten       Builder.restoreIP(SavedIP);
1010ffd1746dSEd Schouten 
1011ffd1746dSEd Schouten       SimplifyCleanupEdges(*this, EHEntry, EHExit);
1012ffd1746dSEd Schouten     }
1013ffd1746dSEd Schouten   }
1014ffd1746dSEd Schouten 
1015ffd1746dSEd Schouten   // If we only have an EH cleanup, we don't really need to do much
1016ffd1746dSEd Schouten   // here.  Branch fixups just naturally drop down to the enclosing
1017ffd1746dSEd Schouten   // cleanup scope.
1018ffd1746dSEd Schouten   if (!Scope.isNormalCleanup()) {
1019ffd1746dSEd Schouten     EHStack.popCleanup();
1020ffd1746dSEd Schouten     assert(EHStack.getNumBranchFixups() == 0 || EHStack.hasNormalCleanups());
1021ffd1746dSEd Schouten     return;
1022ffd1746dSEd Schouten   }
1023ffd1746dSEd Schouten 
1024ffd1746dSEd Schouten   // Check whether the scope has any fixups that need to be threaded.
1025ffd1746dSEd Schouten   unsigned FixupDepth = Scope.getFixupDepth();
1026ffd1746dSEd Schouten   bool HasFixups = EHStack.getNumBranchFixups() != FixupDepth;
1027ffd1746dSEd Schouten 
1028ffd1746dSEd Schouten   // Grab the entry and exit blocks.
1029ffd1746dSEd Schouten   llvm::BasicBlock *Entry = Scope.getNormalEntry();
1030ffd1746dSEd Schouten   llvm::BasicBlock *Exit = Scope.getNormalExit();
1031ffd1746dSEd Schouten 
1032ffd1746dSEd Schouten   // Check whether anything's been threaded through the cleanup already.
1033ffd1746dSEd Schouten   assert((Exit->getTerminator() == 0) == Entry->use_empty() &&
1034ffd1746dSEd Schouten          "cleanup entry/exit mismatch");
1035ffd1746dSEd Schouten   bool HasExistingBranches = !Entry->use_empty();
1036ffd1746dSEd Schouten 
1037ffd1746dSEd Schouten   // Check whether we need to emit a "fallthrough" branch through the
1038ffd1746dSEd Schouten   // cleanup for the current insertion point.
1039ffd1746dSEd Schouten   llvm::BasicBlock *FallThrough = Builder.GetInsertBlock();
1040ffd1746dSEd Schouten   if (FallThrough && FallThrough->getTerminator())
1041ffd1746dSEd Schouten     FallThrough = 0;
1042ffd1746dSEd Schouten 
1043ffd1746dSEd Schouten   // If *nothing* is using the cleanup, kill it.
1044ffd1746dSEd Schouten   if (!FallThrough && !HasFixups && !HasExistingBranches) {
1045ffd1746dSEd Schouten     EHStack.popCleanup();
1046ffd1746dSEd Schouten     DestroyCleanup(*this, Entry, Exit);
1047ffd1746dSEd Schouten     return;
1048ffd1746dSEd Schouten   }
1049ffd1746dSEd Schouten 
1050ffd1746dSEd Schouten   // Otherwise, add the block to the function.
1051ffd1746dSEd Schouten   EmitBlock(Entry);
1052ffd1746dSEd Schouten 
1053ffd1746dSEd Schouten   if (FallThrough)
1054ffd1746dSEd Schouten     Builder.SetInsertPoint(Exit);
1055ffd1746dSEd Schouten   else
1056ffd1746dSEd Schouten     Builder.ClearInsertionPoint();
1057ffd1746dSEd Schouten 
1058ffd1746dSEd Schouten   // Fast case: if we don't have to add any fixups, and either
1059ffd1746dSEd Schouten   // we don't have a fallthrough or the cleanup wasn't previously
1060ffd1746dSEd Schouten   // used, then the setup above is sufficient.
1061ffd1746dSEd Schouten   if (!HasFixups) {
1062ffd1746dSEd Schouten     if (!FallThrough) {
1063ffd1746dSEd Schouten       assert(HasExistingBranches && "no reason for cleanup but didn't kill before");
1064ffd1746dSEd Schouten       EHStack.popCleanup();
1065ffd1746dSEd Schouten       SimplifyCleanupEdges(*this, Entry, Exit);
1066ffd1746dSEd Schouten       return;
1067ffd1746dSEd Schouten     } else if (!HasExistingBranches) {
1068ffd1746dSEd Schouten       assert(FallThrough && "no reason for cleanup but didn't kill before");
1069ffd1746dSEd Schouten       // We can't simplify the exit edge in this case because we're
1070ffd1746dSEd Schouten       // already inserting at the end of the exit block.
1071ffd1746dSEd Schouten       EHStack.popCleanup();
1072ffd1746dSEd Schouten       SimplifyCleanupEntry(*this, Entry);
1073ffd1746dSEd Schouten       return;
1074ffd1746dSEd Schouten     }
1075ffd1746dSEd Schouten   }
1076ffd1746dSEd Schouten 
1077ffd1746dSEd Schouten   // Otherwise we're going to have to thread things through the cleanup.
1078ffd1746dSEd Schouten   llvm::SmallVector<BranchFixup*, 8> Fixups;
1079ffd1746dSEd Schouten 
1080ffd1746dSEd Schouten   // Synthesize a fixup for the current insertion point.
1081ffd1746dSEd Schouten   BranchFixup Cur;
1082ffd1746dSEd Schouten   if (FallThrough) {
1083ffd1746dSEd Schouten     Cur.Destination = createBasicBlock("cleanup.cont");
1084ffd1746dSEd Schouten     Cur.LatestBranch = FallThrough->getTerminator();
1085ffd1746dSEd Schouten     Cur.LatestBranchIndex = 0;
1086ffd1746dSEd Schouten     Cur.Origin = Cur.LatestBranch;
1087ffd1746dSEd Schouten 
1088ffd1746dSEd Schouten     // Restore fixup invariant.  EmitBlock added a branch to the cleanup
1089ffd1746dSEd Schouten     // which we need to redirect to the destination.
1090ffd1746dSEd Schouten     cast<llvm::BranchInst>(Cur.LatestBranch)->setSuccessor(0, Cur.Destination);
1091ffd1746dSEd Schouten 
1092ffd1746dSEd Schouten     Fixups.push_back(&Cur);
1093ffd1746dSEd Schouten   } else {
1094ffd1746dSEd Schouten     Cur.Destination = 0;
1095ffd1746dSEd Schouten   }
1096ffd1746dSEd Schouten 
1097ffd1746dSEd Schouten   // Collect any "real" fixups we need to thread.
1098ffd1746dSEd Schouten   for (unsigned I = FixupDepth, E = EHStack.getNumBranchFixups();
1099ffd1746dSEd Schouten         I != E; ++I)
1100ffd1746dSEd Schouten     if (EHStack.getBranchFixup(I).Destination)
1101ffd1746dSEd Schouten       Fixups.push_back(&EHStack.getBranchFixup(I));
1102ffd1746dSEd Schouten 
1103ffd1746dSEd Schouten   assert(!Fixups.empty() && "no fixups, invariants broken!");
1104ffd1746dSEd Schouten 
1105ffd1746dSEd Schouten   // If there's only a single fixup to thread through, do so with
1106ffd1746dSEd Schouten   // unconditional branches.  This only happens if there's a single
1107ffd1746dSEd Schouten   // branch and no fallthrough.
1108ffd1746dSEd Schouten   if (Fixups.size() == 1 && !HasExistingBranches) {
1109ffd1746dSEd Schouten     Fixups[0]->LatestBranch->setSuccessor(Fixups[0]->LatestBranchIndex, Entry);
1110ffd1746dSEd Schouten     llvm::BranchInst *Br =
1111ffd1746dSEd Schouten       llvm::BranchInst::Create(Fixups[0]->Destination, Exit);
1112ffd1746dSEd Schouten     Fixups[0]->LatestBranch = Br;
1113ffd1746dSEd Schouten     Fixups[0]->LatestBranchIndex = 0;
1114ffd1746dSEd Schouten 
1115ffd1746dSEd Schouten   // Otherwise, force a switch statement and thread everything through
1116ffd1746dSEd Schouten   // the switch.
1117ffd1746dSEd Schouten   } else {
1118ffd1746dSEd Schouten     CreateCleanupSwitch(*this, Exit);
1119ffd1746dSEd Schouten     for (unsigned I = 0, E = Fixups.size(); I != E; ++I)
1120ffd1746dSEd Schouten       ThreadFixupThroughCleanup(*this, *Fixups[I], Entry, Exit);
1121ffd1746dSEd Schouten   }
1122ffd1746dSEd Schouten 
1123ffd1746dSEd Schouten   // Emit the fallthrough destination block if necessary.
1124ffd1746dSEd Schouten   if (Cur.Destination)
1125ffd1746dSEd Schouten     EmitBlock(Cur.Destination);
1126ffd1746dSEd Schouten 
1127ffd1746dSEd Schouten   // We're finally done with the cleanup.
1128ffd1746dSEd Schouten   EHStack.popCleanup();
1129ffd1746dSEd Schouten }
1130ffd1746dSEd Schouten 
1131ffd1746dSEd Schouten void CodeGenFunction::EmitBranchThroughCleanup(JumpDest Dest) {
1132f22ef01cSRoman Divacky   if (!HaveInsertPoint())
1133f22ef01cSRoman Divacky     return;
1134f22ef01cSRoman Divacky 
1135ffd1746dSEd Schouten   // Create the branch.
1136ffd1746dSEd Schouten   llvm::BranchInst *BI = Builder.CreateBr(Dest.Block);
1137ffd1746dSEd Schouten 
1138ffd1746dSEd Schouten   // If we're not in a cleanup scope, we don't need to worry about
1139ffd1746dSEd Schouten   // fixups.
1140ffd1746dSEd Schouten   if (!EHStack.hasNormalCleanups()) {
1141ffd1746dSEd Schouten     Builder.ClearInsertionPoint();
1142ffd1746dSEd Schouten     return;
1143ffd1746dSEd Schouten   }
1144ffd1746dSEd Schouten 
1145ffd1746dSEd Schouten   // Initialize a fixup.
1146ffd1746dSEd Schouten   BranchFixup Fixup;
1147ffd1746dSEd Schouten   Fixup.Destination = Dest.Block;
1148ffd1746dSEd Schouten   Fixup.Origin = BI;
1149ffd1746dSEd Schouten   Fixup.LatestBranch = BI;
1150ffd1746dSEd Schouten   Fixup.LatestBranchIndex = 0;
1151ffd1746dSEd Schouten 
1152ffd1746dSEd Schouten   // If we can't resolve the destination cleanup scope, just add this
1153ffd1746dSEd Schouten   // to the current cleanup scope.
1154ffd1746dSEd Schouten   if (!Dest.ScopeDepth.isValid()) {
1155ffd1746dSEd Schouten     EHStack.addBranchFixup() = Fixup;
1156ffd1746dSEd Schouten     Builder.ClearInsertionPoint();
1157ffd1746dSEd Schouten     return;
1158ffd1746dSEd Schouten   }
1159ffd1746dSEd Schouten 
1160ffd1746dSEd Schouten   for (EHScopeStack::iterator I = EHStack.begin(),
1161ffd1746dSEd Schouten          E = EHStack.find(Dest.ScopeDepth); I != E; ++I) {
1162ffd1746dSEd Schouten     if (isa<EHCleanupScope>(*I)) {
1163ffd1746dSEd Schouten       EHCleanupScope &Scope = cast<EHCleanupScope>(*I);
1164ffd1746dSEd Schouten       if (Scope.isNormalCleanup())
1165ffd1746dSEd Schouten         ThreadFixupThroughCleanup(*this, Fixup, Scope.getNormalEntry(),
1166ffd1746dSEd Schouten                                   Scope.getNormalExit());
1167ffd1746dSEd Schouten     } else if (isa<EHLazyCleanupScope>(*I)) {
1168ffd1746dSEd Schouten       EHLazyCleanupScope &Scope = cast<EHLazyCleanupScope>(*I);
1169ffd1746dSEd Schouten       if (Scope.isNormalCleanup()) {
1170ffd1746dSEd Schouten         llvm::BasicBlock *Block = Scope.getNormalBlock();
1171ffd1746dSEd Schouten         if (!Block) {
1172ffd1746dSEd Schouten           Block = createBasicBlock("cleanup");
1173ffd1746dSEd Schouten           Scope.setNormalBlock(Block);
1174ffd1746dSEd Schouten         }
1175ffd1746dSEd Schouten         ThreadFixupThroughCleanup(*this, Fixup, Block, Block);
1176ffd1746dSEd Schouten       }
1177ffd1746dSEd Schouten     }
1178ffd1746dSEd Schouten   }
1179f22ef01cSRoman Divacky 
1180f22ef01cSRoman Divacky   Builder.ClearInsertionPoint();
1181ffd1746dSEd Schouten }
1182f22ef01cSRoman Divacky 
1183ffd1746dSEd Schouten void CodeGenFunction::EmitBranchThroughEHCleanup(JumpDest Dest) {
1184ffd1746dSEd Schouten   if (!HaveInsertPoint())
1185f22ef01cSRoman Divacky     return;
1186f22ef01cSRoman Divacky 
1187ffd1746dSEd Schouten   // Create the branch.
1188ffd1746dSEd Schouten   llvm::BranchInst *BI = Builder.CreateBr(Dest.Block);
1189ffd1746dSEd Schouten 
1190ffd1746dSEd Schouten   // If we're not in a cleanup scope, we don't need to worry about
1191ffd1746dSEd Schouten   // fixups.
1192ffd1746dSEd Schouten   if (!EHStack.hasEHCleanups()) {
1193ffd1746dSEd Schouten     Builder.ClearInsertionPoint();
1194f22ef01cSRoman Divacky     return;
1195f22ef01cSRoman Divacky   }
1196f22ef01cSRoman Divacky 
1197ffd1746dSEd Schouten   // Initialize a fixup.
1198ffd1746dSEd Schouten   BranchFixup Fixup;
1199ffd1746dSEd Schouten   Fixup.Destination = Dest.Block;
1200ffd1746dSEd Schouten   Fixup.Origin = BI;
1201ffd1746dSEd Schouten   Fixup.LatestBranch = BI;
1202ffd1746dSEd Schouten   Fixup.LatestBranchIndex = 0;
1203ffd1746dSEd Schouten 
1204ffd1746dSEd Schouten   // We should never get invalid scope depths for these: invalid scope
1205ffd1746dSEd Schouten   // depths only arise for as-yet-unemitted labels, and we can't do an
1206ffd1746dSEd Schouten   // EH-unwind to one of those.
1207ffd1746dSEd Schouten   assert(Dest.ScopeDepth.isValid() && "invalid scope depth on EH dest?");
1208ffd1746dSEd Schouten 
1209ffd1746dSEd Schouten   for (EHScopeStack::iterator I = EHStack.begin(),
1210ffd1746dSEd Schouten          E = EHStack.find(Dest.ScopeDepth); I != E; ++I) {
1211ffd1746dSEd Schouten     if (isa<EHCleanupScope>(*I)) {
1212ffd1746dSEd Schouten       EHCleanupScope &Scope = cast<EHCleanupScope>(*I);
1213ffd1746dSEd Schouten       if (Scope.isEHCleanup())
1214ffd1746dSEd Schouten         ThreadFixupThroughCleanup(*this, Fixup, Scope.getEHEntry(),
1215ffd1746dSEd Schouten                                   Scope.getEHExit());
1216ffd1746dSEd Schouten     } else if (isa<EHLazyCleanupScope>(*I)) {
1217ffd1746dSEd Schouten       EHLazyCleanupScope &Scope = cast<EHLazyCleanupScope>(*I);
1218ffd1746dSEd Schouten       if (Scope.isEHCleanup()) {
1219ffd1746dSEd Schouten         llvm::BasicBlock *Block = Scope.getEHBlock();
1220ffd1746dSEd Schouten         if (!Block) {
1221ffd1746dSEd Schouten           Block = createBasicBlock("eh.cleanup");
1222ffd1746dSEd Schouten           Scope.setEHBlock(Block);
1223ffd1746dSEd Schouten         }
1224ffd1746dSEd Schouten         ThreadFixupThroughCleanup(*this, Fixup, Block, Block);
1225ffd1746dSEd Schouten       }
1226ffd1746dSEd Schouten     }
1227f22ef01cSRoman Divacky   }
1228f22ef01cSRoman Divacky 
1229ffd1746dSEd Schouten   Builder.ClearInsertionPoint();
1230f22ef01cSRoman Divacky }
1231