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"
16e580952dSDimitry Andric #include "CGCXXABI.h"
17f22ef01cSRoman Divacky #include "CGDebugInfo.h"
18ffd1746dSEd Schouten #include "CGException.h"
19f22ef01cSRoman Divacky #include "clang/Basic/TargetInfo.h"
20f22ef01cSRoman Divacky #include "clang/AST/APValue.h"
21f22ef01cSRoman Divacky #include "clang/AST/ASTContext.h"
22f22ef01cSRoman Divacky #include "clang/AST/Decl.h"
23f22ef01cSRoman Divacky #include "clang/AST/DeclCXX.h"
24f22ef01cSRoman Divacky #include "clang/AST/StmtCXX.h"
25ffd1746dSEd Schouten #include "clang/Frontend/CodeGenOptions.h"
26f22ef01cSRoman Divacky #include "llvm/Target/TargetData.h"
27ffd1746dSEd Schouten #include "llvm/Intrinsics.h"
28f22ef01cSRoman Divacky using namespace clang;
29f22ef01cSRoman Divacky using namespace CodeGen;
30f22ef01cSRoman Divacky 
31f22ef01cSRoman Divacky CodeGenFunction::CodeGenFunction(CodeGenModule &cgm)
322754fe60SDimitry Andric   : CodeGenTypeCache(cgm), CGM(cgm),
332754fe60SDimitry Andric     Target(CGM.getContext().Target), Builder(cgm.getModule().getContext()),
342754fe60SDimitry Andric     BlockInfo(0), BlockPointer(0),
35e580952dSDimitry Andric     NormalCleanupDest(0), EHCleanupDest(0), NextCleanupDestIndex(1),
36bd5abe19SDimitry Andric     ExceptionSlot(0), EHSelectorSlot(0),
37bd5abe19SDimitry Andric     DebugInfo(0), DisableDebugInfo(false), DidCallStackSave(false),
38bd5abe19SDimitry Andric     IndirectBranch(0), SwitchInsn(0), CaseRangeBlock(0), UnreachableBlock(0),
39f22ef01cSRoman Divacky     CXXThisDecl(0), CXXThisValue(0), CXXVTTDecl(0), CXXVTTValue(0),
402754fe60SDimitry Andric     OutermostConditional(0), TerminateLandingPad(0), TerminateHandler(0),
41ffd1746dSEd Schouten     TrapBB(0) {
42ffd1746dSEd Schouten 
43f22ef01cSRoman Divacky   CatchUndefined = getContext().getLangOptions().CatchUndefined;
44e580952dSDimitry Andric   CGM.getCXXABI().getMangleContext().startNewFunction();
45f22ef01cSRoman Divacky }
46f22ef01cSRoman Divacky 
47f22ef01cSRoman Divacky 
48f22ef01cSRoman Divacky const llvm::Type *CodeGenFunction::ConvertTypeForMem(QualType T) {
49f22ef01cSRoman Divacky   return CGM.getTypes().ConvertTypeForMem(T);
50f22ef01cSRoman Divacky }
51f22ef01cSRoman Divacky 
52f22ef01cSRoman Divacky const llvm::Type *CodeGenFunction::ConvertType(QualType T) {
53f22ef01cSRoman Divacky   return CGM.getTypes().ConvertType(T);
54f22ef01cSRoman Divacky }
55f22ef01cSRoman Divacky 
56bd5abe19SDimitry Andric bool CodeGenFunction::hasAggregateLLVMType(QualType type) {
57bd5abe19SDimitry Andric   switch (type.getCanonicalType()->getTypeClass()) {
58bd5abe19SDimitry Andric #define TYPE(name, parent)
59bd5abe19SDimitry Andric #define ABSTRACT_TYPE(name, parent)
60bd5abe19SDimitry Andric #define NON_CANONICAL_TYPE(name, parent) case Type::name:
61bd5abe19SDimitry Andric #define DEPENDENT_TYPE(name, parent) case Type::name:
62bd5abe19SDimitry Andric #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(name, parent) case Type::name:
63bd5abe19SDimitry Andric #include "clang/AST/TypeNodes.def"
64bd5abe19SDimitry Andric     llvm_unreachable("non-canonical or dependent type in IR-generation");
65bd5abe19SDimitry Andric 
66bd5abe19SDimitry Andric   case Type::Builtin:
67bd5abe19SDimitry Andric   case Type::Pointer:
68bd5abe19SDimitry Andric   case Type::BlockPointer:
69bd5abe19SDimitry Andric   case Type::LValueReference:
70bd5abe19SDimitry Andric   case Type::RValueReference:
71bd5abe19SDimitry Andric   case Type::MemberPointer:
72bd5abe19SDimitry Andric   case Type::Vector:
73bd5abe19SDimitry Andric   case Type::ExtVector:
74bd5abe19SDimitry Andric   case Type::FunctionProto:
75bd5abe19SDimitry Andric   case Type::FunctionNoProto:
76bd5abe19SDimitry Andric   case Type::Enum:
77bd5abe19SDimitry Andric   case Type::ObjCObjectPointer:
78bd5abe19SDimitry Andric     return false;
79bd5abe19SDimitry Andric 
80bd5abe19SDimitry Andric   // Complexes, arrays, records, and Objective-C objects.
81bd5abe19SDimitry Andric   case Type::Complex:
82bd5abe19SDimitry Andric   case Type::ConstantArray:
83bd5abe19SDimitry Andric   case Type::IncompleteArray:
84bd5abe19SDimitry Andric   case Type::VariableArray:
85bd5abe19SDimitry Andric   case Type::Record:
86bd5abe19SDimitry Andric   case Type::ObjCObject:
87bd5abe19SDimitry Andric   case Type::ObjCInterface:
88bd5abe19SDimitry Andric     return true;
89bd5abe19SDimitry Andric   }
90bd5abe19SDimitry Andric   llvm_unreachable("unknown type kind!");
91f22ef01cSRoman Divacky }
92f22ef01cSRoman Divacky 
93f22ef01cSRoman Divacky void CodeGenFunction::EmitReturnBlock() {
94f22ef01cSRoman Divacky   // For cleanliness, we try to avoid emitting the return block for
95f22ef01cSRoman Divacky   // simple cases.
96f22ef01cSRoman Divacky   llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
97f22ef01cSRoman Divacky 
98f22ef01cSRoman Divacky   if (CurBB) {
99f22ef01cSRoman Divacky     assert(!CurBB->getTerminator() && "Unexpected terminated block.");
100f22ef01cSRoman Divacky 
101f22ef01cSRoman Divacky     // We have a valid insert point, reuse it if it is empty or there are no
102f22ef01cSRoman Divacky     // explicit jumps to the return block.
103e580952dSDimitry Andric     if (CurBB->empty() || ReturnBlock.getBlock()->use_empty()) {
104e580952dSDimitry Andric       ReturnBlock.getBlock()->replaceAllUsesWith(CurBB);
105e580952dSDimitry Andric       delete ReturnBlock.getBlock();
106f22ef01cSRoman Divacky     } else
107e580952dSDimitry Andric       EmitBlock(ReturnBlock.getBlock());
108f22ef01cSRoman Divacky     return;
109f22ef01cSRoman Divacky   }
110f22ef01cSRoman Divacky 
111f22ef01cSRoman Divacky   // Otherwise, if the return block is the target of a single direct
112f22ef01cSRoman Divacky   // branch then we can just put the code in that block instead. This
113f22ef01cSRoman Divacky   // cleans up functions which started with a unified return block.
114e580952dSDimitry Andric   if (ReturnBlock.getBlock()->hasOneUse()) {
115f22ef01cSRoman Divacky     llvm::BranchInst *BI =
116e580952dSDimitry Andric       dyn_cast<llvm::BranchInst>(*ReturnBlock.getBlock()->use_begin());
117ffd1746dSEd Schouten     if (BI && BI->isUnconditional() &&
118e580952dSDimitry Andric         BI->getSuccessor(0) == ReturnBlock.getBlock()) {
119f22ef01cSRoman Divacky       // Reset insertion point and delete the branch.
120f22ef01cSRoman Divacky       Builder.SetInsertPoint(BI->getParent());
121f22ef01cSRoman Divacky       BI->eraseFromParent();
122e580952dSDimitry Andric       delete ReturnBlock.getBlock();
123f22ef01cSRoman Divacky       return;
124f22ef01cSRoman Divacky     }
125f22ef01cSRoman Divacky   }
126f22ef01cSRoman Divacky 
127f22ef01cSRoman Divacky   // FIXME: We are at an unreachable point, there is no reason to emit the block
128f22ef01cSRoman Divacky   // unless it has uses. However, we still need a place to put the debug
129f22ef01cSRoman Divacky   // region.end for now.
130f22ef01cSRoman Divacky 
131e580952dSDimitry Andric   EmitBlock(ReturnBlock.getBlock());
132ffd1746dSEd Schouten }
133ffd1746dSEd Schouten 
134ffd1746dSEd Schouten static void EmitIfUsed(CodeGenFunction &CGF, llvm::BasicBlock *BB) {
135ffd1746dSEd Schouten   if (!BB) return;
136ffd1746dSEd Schouten   if (!BB->use_empty())
137ffd1746dSEd Schouten     return CGF.CurFn->getBasicBlockList().push_back(BB);
138ffd1746dSEd Schouten   delete BB;
139f22ef01cSRoman Divacky }
140f22ef01cSRoman Divacky 
141f22ef01cSRoman Divacky void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
142f22ef01cSRoman Divacky   assert(BreakContinueStack.empty() &&
143f22ef01cSRoman Divacky          "mismatched push/pop in break/continue stack!");
144f22ef01cSRoman Divacky 
145f22ef01cSRoman Divacky   // Emit function epilog (to return).
146f22ef01cSRoman Divacky   EmitReturnBlock();
147f22ef01cSRoman Divacky 
1482754fe60SDimitry Andric   if (ShouldInstrumentFunction())
149ffd1746dSEd Schouten     EmitFunctionInstrumentation("__cyg_profile_func_exit");
150ffd1746dSEd Schouten 
151f22ef01cSRoman Divacky   // Emit debug descriptor for function end.
152f22ef01cSRoman Divacky   if (CGDebugInfo *DI = getDebugInfo()) {
153f22ef01cSRoman Divacky     DI->setLocation(EndLoc);
154e580952dSDimitry Andric     DI->EmitFunctionEnd(Builder);
155f22ef01cSRoman Divacky   }
156f22ef01cSRoman Divacky 
157ffd1746dSEd Schouten   EmitFunctionEpilog(*CurFnInfo);
158f22ef01cSRoman Divacky   EmitEndEHSpec(CurCodeDecl);
159f22ef01cSRoman Divacky 
160ffd1746dSEd Schouten   assert(EHStack.empty() &&
161ffd1746dSEd Schouten          "did not remove all scopes from cleanup stack!");
162ffd1746dSEd Schouten 
163f22ef01cSRoman Divacky   // If someone did an indirect goto, emit the indirect goto block at the end of
164f22ef01cSRoman Divacky   // the function.
165f22ef01cSRoman Divacky   if (IndirectBranch) {
166f22ef01cSRoman Divacky     EmitBlock(IndirectBranch->getParent());
167f22ef01cSRoman Divacky     Builder.ClearInsertionPoint();
168f22ef01cSRoman Divacky   }
169f22ef01cSRoman Divacky 
170f22ef01cSRoman Divacky   // Remove the AllocaInsertPt instruction, which is just a convenience for us.
171f22ef01cSRoman Divacky   llvm::Instruction *Ptr = AllocaInsertPt;
172f22ef01cSRoman Divacky   AllocaInsertPt = 0;
173f22ef01cSRoman Divacky   Ptr->eraseFromParent();
174f22ef01cSRoman Divacky 
175f22ef01cSRoman Divacky   // If someone took the address of a label but never did an indirect goto, we
176f22ef01cSRoman Divacky   // made a zero entry PHI node, which is illegal, zap it now.
177f22ef01cSRoman Divacky   if (IndirectBranch) {
178f22ef01cSRoman Divacky     llvm::PHINode *PN = cast<llvm::PHINode>(IndirectBranch->getAddress());
179f22ef01cSRoman Divacky     if (PN->getNumIncomingValues() == 0) {
180f22ef01cSRoman Divacky       PN->replaceAllUsesWith(llvm::UndefValue::get(PN->getType()));
181f22ef01cSRoman Divacky       PN->eraseFromParent();
182f22ef01cSRoman Divacky     }
183f22ef01cSRoman Divacky   }
184ffd1746dSEd Schouten 
185e580952dSDimitry Andric   EmitIfUsed(*this, RethrowBlock.getBlock());
186ffd1746dSEd Schouten   EmitIfUsed(*this, TerminateLandingPad);
187ffd1746dSEd Schouten   EmitIfUsed(*this, TerminateHandler);
188ffd1746dSEd Schouten   EmitIfUsed(*this, UnreachableBlock);
189ffd1746dSEd Schouten 
190ffd1746dSEd Schouten   if (CGM.getCodeGenOpts().EmitDeclMetadata)
191ffd1746dSEd Schouten     EmitDeclMetadata();
192ffd1746dSEd Schouten }
193ffd1746dSEd Schouten 
194ffd1746dSEd Schouten /// ShouldInstrumentFunction - Return true if the current function should be
195ffd1746dSEd Schouten /// instrumented with __cyg_profile_func_* calls
196ffd1746dSEd Schouten bool CodeGenFunction::ShouldInstrumentFunction() {
197ffd1746dSEd Schouten   if (!CGM.getCodeGenOpts().InstrumentFunctions)
198ffd1746dSEd Schouten     return false;
199bd5abe19SDimitry Andric   if (!CurFuncDecl || CurFuncDecl->hasAttr<NoInstrumentFunctionAttr>())
200ffd1746dSEd Schouten     return false;
201ffd1746dSEd Schouten   return true;
202ffd1746dSEd Schouten }
203ffd1746dSEd Schouten 
204ffd1746dSEd Schouten /// EmitFunctionInstrumentation - Emit LLVM code to call the specified
205ffd1746dSEd Schouten /// instrumentation function with the current function and the call site, if
206ffd1746dSEd Schouten /// function instrumentation is enabled.
207ffd1746dSEd Schouten void CodeGenFunction::EmitFunctionInstrumentation(const char *Fn) {
208ffd1746dSEd Schouten   // void __cyg_profile_func_{enter,exit} (void *this_fn, void *call_site);
209bd5abe19SDimitry Andric   const llvm::PointerType *PointerTy = Int8PtrTy;
210bd5abe19SDimitry Andric   const llvm::Type *ProfileFuncArgs[] = { PointerTy, PointerTy };
211bd5abe19SDimitry Andric   const llvm::FunctionType *FunctionTy =
212bd5abe19SDimitry Andric     llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()),
213ffd1746dSEd Schouten                             ProfileFuncArgs, false);
214ffd1746dSEd Schouten 
215ffd1746dSEd Schouten   llvm::Constant *F = CGM.CreateRuntimeFunction(FunctionTy, Fn);
216ffd1746dSEd Schouten   llvm::CallInst *CallSite = Builder.CreateCall(
217ffd1746dSEd Schouten     CGM.getIntrinsic(llvm::Intrinsic::returnaddress, 0, 0),
218ffd1746dSEd Schouten     llvm::ConstantInt::get(Int32Ty, 0),
219ffd1746dSEd Schouten     "callsite");
220ffd1746dSEd Schouten 
221ffd1746dSEd Schouten   Builder.CreateCall2(F,
222ffd1746dSEd Schouten                       llvm::ConstantExpr::getBitCast(CurFn, PointerTy),
223ffd1746dSEd Schouten                       CallSite);
224f22ef01cSRoman Divacky }
225f22ef01cSRoman Divacky 
2262754fe60SDimitry Andric void CodeGenFunction::EmitMCountInstrumentation() {
2272754fe60SDimitry Andric   llvm::FunctionType *FTy =
2282754fe60SDimitry Andric     llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()), false);
2292754fe60SDimitry Andric 
2302754fe60SDimitry Andric   llvm::Constant *MCountFn = CGM.CreateRuntimeFunction(FTy,
2312754fe60SDimitry Andric                                                        Target.getMCountName());
2322754fe60SDimitry Andric   Builder.CreateCall(MCountFn);
2332754fe60SDimitry Andric }
2342754fe60SDimitry Andric 
235f22ef01cSRoman Divacky void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
236f22ef01cSRoman Divacky                                     llvm::Function *Fn,
2373b0f4066SDimitry Andric                                     const CGFunctionInfo &FnInfo,
238f22ef01cSRoman Divacky                                     const FunctionArgList &Args,
239f22ef01cSRoman Divacky                                     SourceLocation StartLoc) {
240f22ef01cSRoman Divacky   const Decl *D = GD.getDecl();
241f22ef01cSRoman Divacky 
242f22ef01cSRoman Divacky   DidCallStackSave = false;
243f22ef01cSRoman Divacky   CurCodeDecl = CurFuncDecl = D;
244f22ef01cSRoman Divacky   FnRetTy = RetTy;
245f22ef01cSRoman Divacky   CurFn = Fn;
2463b0f4066SDimitry Andric   CurFnInfo = &FnInfo;
247f22ef01cSRoman Divacky   assert(CurFn->isDeclaration() && "Function already has body?");
248f22ef01cSRoman Divacky 
249f22ef01cSRoman Divacky   // Pass inline keyword to optimizer if it appears explicitly on any
250f22ef01cSRoman Divacky   // declaration.
251f22ef01cSRoman Divacky   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
252f22ef01cSRoman Divacky     for (FunctionDecl::redecl_iterator RI = FD->redecls_begin(),
253f22ef01cSRoman Divacky            RE = FD->redecls_end(); RI != RE; ++RI)
254f22ef01cSRoman Divacky       if (RI->isInlineSpecified()) {
255f22ef01cSRoman Divacky         Fn->addFnAttr(llvm::Attribute::InlineHint);
256f22ef01cSRoman Divacky         break;
257f22ef01cSRoman Divacky       }
258f22ef01cSRoman Divacky 
2592754fe60SDimitry Andric   if (getContext().getLangOptions().OpenCL) {
2602754fe60SDimitry Andric     // Add metadata for a kernel function.
2612754fe60SDimitry Andric     if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
2622754fe60SDimitry Andric       if (FD->hasAttr<OpenCLKernelAttr>()) {
2632754fe60SDimitry Andric         llvm::LLVMContext &Context = getLLVMContext();
2642754fe60SDimitry Andric         llvm::NamedMDNode *OpenCLMetadata =
2652754fe60SDimitry Andric           CGM.getModule().getOrInsertNamedMetadata("opencl.kernels");
2662754fe60SDimitry Andric 
2672754fe60SDimitry Andric         llvm::Value *Op = Fn;
2683b0f4066SDimitry Andric         OpenCLMetadata->addOperand(llvm::MDNode::get(Context, Op));
2692754fe60SDimitry Andric       }
2702754fe60SDimitry Andric   }
2712754fe60SDimitry Andric 
272f22ef01cSRoman Divacky   llvm::BasicBlock *EntryBB = createBasicBlock("entry", CurFn);
273f22ef01cSRoman Divacky 
274f22ef01cSRoman Divacky   // Create a marker to make it easy to insert allocas into the entryblock
275f22ef01cSRoman Divacky   // later.  Don't create this with the builder, because we don't want it
276f22ef01cSRoman Divacky   // folded.
277ffd1746dSEd Schouten   llvm::Value *Undef = llvm::UndefValue::get(Int32Ty);
278ffd1746dSEd Schouten   AllocaInsertPt = new llvm::BitCastInst(Undef, Int32Ty, "", EntryBB);
279f22ef01cSRoman Divacky   if (Builder.isNamePreserving())
280f22ef01cSRoman Divacky     AllocaInsertPt->setName("allocapt");
281f22ef01cSRoman Divacky 
282ffd1746dSEd Schouten   ReturnBlock = getJumpDestInCurrentScope("return");
283f22ef01cSRoman Divacky 
284f22ef01cSRoman Divacky   Builder.SetInsertPoint(EntryBB);
285f22ef01cSRoman Divacky 
286f22ef01cSRoman Divacky   // Emit subprogram debug descriptor.
287f22ef01cSRoman Divacky   if (CGDebugInfo *DI = getDebugInfo()) {
2882754fe60SDimitry Andric     // FIXME: what is going on here and why does it ignore all these
2892754fe60SDimitry Andric     // interesting type properties?
2902754fe60SDimitry Andric     QualType FnType =
2912754fe60SDimitry Andric       getContext().getFunctionType(RetTy, 0, 0,
2922754fe60SDimitry Andric                                    FunctionProtoType::ExtProtoInfo());
2932754fe60SDimitry Andric 
294f22ef01cSRoman Divacky     DI->setLocation(StartLoc);
295f22ef01cSRoman Divacky     DI->EmitFunctionStart(GD, FnType, CurFn, Builder);
296f22ef01cSRoman Divacky   }
297f22ef01cSRoman Divacky 
2982754fe60SDimitry Andric   if (ShouldInstrumentFunction())
299ffd1746dSEd Schouten     EmitFunctionInstrumentation("__cyg_profile_func_enter");
300ffd1746dSEd Schouten 
3012754fe60SDimitry Andric   if (CGM.getCodeGenOpts().InstrumentForProfiling)
3022754fe60SDimitry Andric     EmitMCountInstrumentation();
3032754fe60SDimitry Andric 
304f22ef01cSRoman Divacky   if (RetTy->isVoidType()) {
305f22ef01cSRoman Divacky     // Void type; nothing to return.
306f22ef01cSRoman Divacky     ReturnValue = 0;
307f22ef01cSRoman Divacky   } else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect &&
308f22ef01cSRoman Divacky              hasAggregateLLVMType(CurFnInfo->getReturnType())) {
309f22ef01cSRoman Divacky     // Indirect aggregate return; emit returned value directly into sret slot.
310f22ef01cSRoman Divacky     // This reduces code size, and affects correctness in C++.
311f22ef01cSRoman Divacky     ReturnValue = CurFn->arg_begin();
312f22ef01cSRoman Divacky   } else {
313f22ef01cSRoman Divacky     ReturnValue = CreateIRTemp(RetTy, "retval");
314f22ef01cSRoman Divacky   }
315f22ef01cSRoman Divacky 
316f22ef01cSRoman Divacky   EmitStartEHSpec(CurCodeDecl);
317f22ef01cSRoman Divacky   EmitFunctionProlog(*CurFnInfo, CurFn, Args);
318f22ef01cSRoman Divacky 
319e580952dSDimitry Andric   if (D && isa<CXXMethodDecl>(D) && cast<CXXMethodDecl>(D)->isInstance())
320e580952dSDimitry Andric     CGM.getCXXABI().EmitInstanceFunctionProlog(*this);
321f22ef01cSRoman Divacky 
322f22ef01cSRoman Divacky   // If any of the arguments have a variably modified type, make sure to
323f22ef01cSRoman Divacky   // emit the type size.
324f22ef01cSRoman Divacky   for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
325f22ef01cSRoman Divacky        i != e; ++i) {
3263b0f4066SDimitry Andric     QualType Ty = (*i)->getType();
327f22ef01cSRoman Divacky 
328f22ef01cSRoman Divacky     if (Ty->isVariablyModifiedType())
329f22ef01cSRoman Divacky       EmitVLASize(Ty);
330f22ef01cSRoman Divacky   }
331f22ef01cSRoman Divacky }
332f22ef01cSRoman Divacky 
333f22ef01cSRoman Divacky void CodeGenFunction::EmitFunctionBody(FunctionArgList &Args) {
334f22ef01cSRoman Divacky   const FunctionDecl *FD = cast<FunctionDecl>(CurGD.getDecl());
335f22ef01cSRoman Divacky   assert(FD->getBody());
336f22ef01cSRoman Divacky   EmitStmt(FD->getBody());
337f22ef01cSRoman Divacky }
338f22ef01cSRoman Divacky 
339e580952dSDimitry Andric /// Tries to mark the given function nounwind based on the
340e580952dSDimitry Andric /// non-existence of any throwing calls within it.  We believe this is
341e580952dSDimitry Andric /// lightweight enough to do at -O0.
342e580952dSDimitry Andric static void TryMarkNoThrow(llvm::Function *F) {
343e580952dSDimitry Andric   // LLVM treats 'nounwind' on a function as part of the type, so we
344e580952dSDimitry Andric   // can't do this on functions that can be overwritten.
345e580952dSDimitry Andric   if (F->mayBeOverridden()) return;
346e580952dSDimitry Andric 
347e580952dSDimitry Andric   for (llvm::Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI)
348e580952dSDimitry Andric     for (llvm::BasicBlock::iterator
349e580952dSDimitry Andric            BI = FI->begin(), BE = FI->end(); BI != BE; ++BI)
350e580952dSDimitry Andric       if (llvm::CallInst *Call = dyn_cast<llvm::CallInst>(&*BI))
351e580952dSDimitry Andric         if (!Call->doesNotThrow())
352e580952dSDimitry Andric           return;
353e580952dSDimitry Andric   F->setDoesNotThrow(true);
354e580952dSDimitry Andric }
355e580952dSDimitry Andric 
3563b0f4066SDimitry Andric void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
3573b0f4066SDimitry Andric                                    const CGFunctionInfo &FnInfo) {
358f22ef01cSRoman Divacky   const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
359f22ef01cSRoman Divacky 
360f22ef01cSRoman Divacky   // Check if we should generate debug info for this function.
3613b0f4066SDimitry Andric   if (CGM.getModuleDebugInfo() && !FD->hasAttr<NoDebugAttr>())
3623b0f4066SDimitry Andric     DebugInfo = CGM.getModuleDebugInfo();
363f22ef01cSRoman Divacky 
364f22ef01cSRoman Divacky   FunctionArgList Args;
365e580952dSDimitry Andric   QualType ResTy = FD->getResultType();
366f22ef01cSRoman Divacky 
367f22ef01cSRoman Divacky   CurGD = GD;
368e580952dSDimitry Andric   if (isa<CXXMethodDecl>(FD) && cast<CXXMethodDecl>(FD)->isInstance())
369e580952dSDimitry Andric     CGM.getCXXABI().BuildInstanceFunctionParams(*this, ResTy, Args);
370f22ef01cSRoman Divacky 
3713b0f4066SDimitry Andric   if (FD->getNumParams())
372f22ef01cSRoman Divacky     for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i)
3733b0f4066SDimitry Andric       Args.push_back(FD->getParamDecl(i));
374f22ef01cSRoman Divacky 
375f22ef01cSRoman Divacky   SourceRange BodyRange;
376f22ef01cSRoman Divacky   if (Stmt *Body = FD->getBody()) BodyRange = Body->getSourceRange();
377f22ef01cSRoman Divacky 
378f22ef01cSRoman Divacky   // Emit the standard function prologue.
3793b0f4066SDimitry Andric   StartFunction(GD, ResTy, Fn, FnInfo, Args, BodyRange.getBegin());
380f22ef01cSRoman Divacky 
381f22ef01cSRoman Divacky   // Generate the body of the function.
382f22ef01cSRoman Divacky   if (isa<CXXDestructorDecl>(FD))
383f22ef01cSRoman Divacky     EmitDestructorBody(Args);
384f22ef01cSRoman Divacky   else if (isa<CXXConstructorDecl>(FD))
385f22ef01cSRoman Divacky     EmitConstructorBody(Args);
386f22ef01cSRoman Divacky   else
387f22ef01cSRoman Divacky     EmitFunctionBody(Args);
388f22ef01cSRoman Divacky 
389f22ef01cSRoman Divacky   // Emit the standard function epilogue.
390f22ef01cSRoman Divacky   FinishFunction(BodyRange.getEnd());
391f22ef01cSRoman Divacky 
392e580952dSDimitry Andric   // If we haven't marked the function nothrow through other means, do
393e580952dSDimitry Andric   // a quick pass now to see if we can.
394e580952dSDimitry Andric   if (!CurFn->doesNotThrow())
395e580952dSDimitry Andric     TryMarkNoThrow(CurFn);
396f22ef01cSRoman Divacky }
397f22ef01cSRoman Divacky 
398f22ef01cSRoman Divacky /// ContainsLabel - Return true if the statement contains a label in it.  If
399f22ef01cSRoman Divacky /// this statement is not executed normally, it not containing a label means
400f22ef01cSRoman Divacky /// that we can just remove the code.
401f22ef01cSRoman Divacky bool CodeGenFunction::ContainsLabel(const Stmt *S, bool IgnoreCaseStmts) {
402f22ef01cSRoman Divacky   // Null statement, not a label!
403f22ef01cSRoman Divacky   if (S == 0) return false;
404f22ef01cSRoman Divacky 
405f22ef01cSRoman Divacky   // If this is a label, we have to emit the code, consider something like:
406f22ef01cSRoman Divacky   // if (0) {  ...  foo:  bar(); }  goto foo;
4073b0f4066SDimitry Andric   //
4083b0f4066SDimitry Andric   // TODO: If anyone cared, we could track __label__'s, since we know that you
4093b0f4066SDimitry Andric   // can't jump to one from outside their declared region.
410f22ef01cSRoman Divacky   if (isa<LabelStmt>(S))
411f22ef01cSRoman Divacky     return true;
412f22ef01cSRoman Divacky 
413f22ef01cSRoman Divacky   // If this is a case/default statement, and we haven't seen a switch, we have
414f22ef01cSRoman Divacky   // to emit the code.
415f22ef01cSRoman Divacky   if (isa<SwitchCase>(S) && !IgnoreCaseStmts)
416f22ef01cSRoman Divacky     return true;
417f22ef01cSRoman Divacky 
418f22ef01cSRoman Divacky   // If this is a switch statement, we want to ignore cases below it.
419f22ef01cSRoman Divacky   if (isa<SwitchStmt>(S))
420f22ef01cSRoman Divacky     IgnoreCaseStmts = true;
421f22ef01cSRoman Divacky 
422f22ef01cSRoman Divacky   // Scan subexpressions for verboten labels.
4232754fe60SDimitry Andric   for (Stmt::const_child_range I = S->children(); I; ++I)
424f22ef01cSRoman Divacky     if (ContainsLabel(*I, IgnoreCaseStmts))
425f22ef01cSRoman Divacky       return true;
426f22ef01cSRoman Divacky 
427f22ef01cSRoman Divacky   return false;
428f22ef01cSRoman Divacky }
429f22ef01cSRoman Divacky 
4303b0f4066SDimitry Andric /// containsBreak - Return true if the statement contains a break out of it.
4313b0f4066SDimitry Andric /// If the statement (recursively) contains a switch or loop with a break
4323b0f4066SDimitry Andric /// inside of it, this is fine.
4333b0f4066SDimitry Andric bool CodeGenFunction::containsBreak(const Stmt *S) {
4343b0f4066SDimitry Andric   // Null statement, not a label!
4353b0f4066SDimitry Andric   if (S == 0) return false;
436f22ef01cSRoman Divacky 
4373b0f4066SDimitry Andric   // If this is a switch or loop that defines its own break scope, then we can
4383b0f4066SDimitry Andric   // include it and anything inside of it.
4393b0f4066SDimitry Andric   if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || isa<DoStmt>(S) ||
4403b0f4066SDimitry Andric       isa<ForStmt>(S))
4413b0f4066SDimitry Andric     return false;
4423b0f4066SDimitry Andric 
4433b0f4066SDimitry Andric   if (isa<BreakStmt>(S))
4443b0f4066SDimitry Andric     return true;
4453b0f4066SDimitry Andric 
4463b0f4066SDimitry Andric   // Scan subexpressions for verboten breaks.
4473b0f4066SDimitry Andric   for (Stmt::const_child_range I = S->children(); I; ++I)
4483b0f4066SDimitry Andric     if (containsBreak(*I))
4493b0f4066SDimitry Andric       return true;
4503b0f4066SDimitry Andric 
4513b0f4066SDimitry Andric   return false;
4523b0f4066SDimitry Andric }
4533b0f4066SDimitry Andric 
4543b0f4066SDimitry Andric 
4553b0f4066SDimitry Andric /// ConstantFoldsToSimpleInteger - If the specified expression does not fold
4563b0f4066SDimitry Andric /// to a constant, or if it does but contains a label, return false.  If it
4573b0f4066SDimitry Andric /// constant folds return true and set the boolean result in Result.
4583b0f4066SDimitry Andric bool CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond,
4593b0f4066SDimitry Andric                                                    bool &ResultBool) {
4603b0f4066SDimitry Andric   llvm::APInt ResultInt;
4613b0f4066SDimitry Andric   if (!ConstantFoldsToSimpleInteger(Cond, ResultInt))
4623b0f4066SDimitry Andric     return false;
4633b0f4066SDimitry Andric 
4643b0f4066SDimitry Andric   ResultBool = ResultInt.getBoolValue();
4653b0f4066SDimitry Andric   return true;
4663b0f4066SDimitry Andric }
4673b0f4066SDimitry Andric 
4683b0f4066SDimitry Andric /// ConstantFoldsToSimpleInteger - If the specified expression does not fold
4693b0f4066SDimitry Andric /// to a constant, or if it does but contains a label, return false.  If it
4703b0f4066SDimitry Andric /// constant folds return true and set the folded value.
4713b0f4066SDimitry Andric bool CodeGenFunction::
4723b0f4066SDimitry Andric ConstantFoldsToSimpleInteger(const Expr *Cond, llvm::APInt &ResultInt) {
473f22ef01cSRoman Divacky   // FIXME: Rename and handle conversion of other evaluatable things
474f22ef01cSRoman Divacky   // to bool.
475f22ef01cSRoman Divacky   Expr::EvalResult Result;
476f22ef01cSRoman Divacky   if (!Cond->Evaluate(Result, getContext()) || !Result.Val.isInt() ||
477f22ef01cSRoman Divacky       Result.HasSideEffects)
4783b0f4066SDimitry Andric     return false;  // Not foldable, not integer or not fully evaluatable.
479f22ef01cSRoman Divacky 
480f22ef01cSRoman Divacky   if (CodeGenFunction::ContainsLabel(Cond))
4813b0f4066SDimitry Andric     return false;  // Contains a label.
482f22ef01cSRoman Divacky 
4833b0f4066SDimitry Andric   ResultInt = Result.Val.getInt();
4843b0f4066SDimitry Andric   return true;
485f22ef01cSRoman Divacky }
486f22ef01cSRoman Divacky 
487f22ef01cSRoman Divacky 
4883b0f4066SDimitry Andric 
489f22ef01cSRoman Divacky /// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an if
490f22ef01cSRoman Divacky /// statement) to the specified blocks.  Based on the condition, this might try
491f22ef01cSRoman Divacky /// to simplify the codegen of the conditional based on the branch.
492f22ef01cSRoman Divacky ///
493f22ef01cSRoman Divacky void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond,
494f22ef01cSRoman Divacky                                            llvm::BasicBlock *TrueBlock,
495f22ef01cSRoman Divacky                                            llvm::BasicBlock *FalseBlock) {
4963b0f4066SDimitry Andric   Cond = Cond->IgnoreParens();
497f22ef01cSRoman Divacky 
498f22ef01cSRoman Divacky   if (const BinaryOperator *CondBOp = dyn_cast<BinaryOperator>(Cond)) {
499f22ef01cSRoman Divacky     // Handle X && Y in a condition.
500e580952dSDimitry Andric     if (CondBOp->getOpcode() == BO_LAnd) {
501f22ef01cSRoman Divacky       // If we have "1 && X", simplify the code.  "0 && X" would have constant
502f22ef01cSRoman Divacky       // folded if the case was simple enough.
5033b0f4066SDimitry Andric       bool ConstantBool = false;
5043b0f4066SDimitry Andric       if (ConstantFoldsToSimpleInteger(CondBOp->getLHS(), ConstantBool) &&
5053b0f4066SDimitry Andric           ConstantBool) {
506f22ef01cSRoman Divacky         // br(1 && X) -> br(X).
507f22ef01cSRoman Divacky         return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
508f22ef01cSRoman Divacky       }
509f22ef01cSRoman Divacky 
510f22ef01cSRoman Divacky       // If we have "X && 1", simplify the code to use an uncond branch.
511f22ef01cSRoman Divacky       // "X && 0" would have been constant folded to 0.
5123b0f4066SDimitry Andric       if (ConstantFoldsToSimpleInteger(CondBOp->getRHS(), ConstantBool) &&
5133b0f4066SDimitry Andric           ConstantBool) {
514f22ef01cSRoman Divacky         // br(X && 1) -> br(X).
515f22ef01cSRoman Divacky         return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock);
516f22ef01cSRoman Divacky       }
517f22ef01cSRoman Divacky 
518f22ef01cSRoman Divacky       // Emit the LHS as a conditional.  If the LHS conditional is false, we
519f22ef01cSRoman Divacky       // want to jump to the FalseBlock.
520f22ef01cSRoman Divacky       llvm::BasicBlock *LHSTrue = createBasicBlock("land.lhs.true");
5212754fe60SDimitry Andric 
5222754fe60SDimitry Andric       ConditionalEvaluation eval(*this);
523f22ef01cSRoman Divacky       EmitBranchOnBoolExpr(CondBOp->getLHS(), LHSTrue, FalseBlock);
524f22ef01cSRoman Divacky       EmitBlock(LHSTrue);
525f22ef01cSRoman Divacky 
526f22ef01cSRoman Divacky       // Any temporaries created here are conditional.
5272754fe60SDimitry Andric       eval.begin(*this);
528f22ef01cSRoman Divacky       EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
5292754fe60SDimitry Andric       eval.end(*this);
530f22ef01cSRoman Divacky 
531f22ef01cSRoman Divacky       return;
5323b0f4066SDimitry Andric     }
5333b0f4066SDimitry Andric 
5343b0f4066SDimitry Andric     if (CondBOp->getOpcode() == BO_LOr) {
535f22ef01cSRoman Divacky       // If we have "0 || X", simplify the code.  "1 || X" would have constant
536f22ef01cSRoman Divacky       // folded if the case was simple enough.
5373b0f4066SDimitry Andric       bool ConstantBool = false;
5383b0f4066SDimitry Andric       if (ConstantFoldsToSimpleInteger(CondBOp->getLHS(), ConstantBool) &&
5393b0f4066SDimitry Andric           !ConstantBool) {
540f22ef01cSRoman Divacky         // br(0 || X) -> br(X).
541f22ef01cSRoman Divacky         return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
542f22ef01cSRoman Divacky       }
543f22ef01cSRoman Divacky 
544f22ef01cSRoman Divacky       // If we have "X || 0", simplify the code to use an uncond branch.
545f22ef01cSRoman Divacky       // "X || 1" would have been constant folded to 1.
5463b0f4066SDimitry Andric       if (ConstantFoldsToSimpleInteger(CondBOp->getRHS(), ConstantBool) &&
5473b0f4066SDimitry Andric           !ConstantBool) {
548f22ef01cSRoman Divacky         // br(X || 0) -> br(X).
549f22ef01cSRoman Divacky         return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock);
550f22ef01cSRoman Divacky       }
551f22ef01cSRoman Divacky 
552f22ef01cSRoman Divacky       // Emit the LHS as a conditional.  If the LHS conditional is true, we
553f22ef01cSRoman Divacky       // want to jump to the TrueBlock.
554f22ef01cSRoman Divacky       llvm::BasicBlock *LHSFalse = createBasicBlock("lor.lhs.false");
5552754fe60SDimitry Andric 
5562754fe60SDimitry Andric       ConditionalEvaluation eval(*this);
557f22ef01cSRoman Divacky       EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, LHSFalse);
558f22ef01cSRoman Divacky       EmitBlock(LHSFalse);
559f22ef01cSRoman Divacky 
560f22ef01cSRoman Divacky       // Any temporaries created here are conditional.
5612754fe60SDimitry Andric       eval.begin(*this);
562f22ef01cSRoman Divacky       EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
5632754fe60SDimitry Andric       eval.end(*this);
564f22ef01cSRoman Divacky 
565f22ef01cSRoman Divacky       return;
566f22ef01cSRoman Divacky     }
567f22ef01cSRoman Divacky   }
568f22ef01cSRoman Divacky 
569f22ef01cSRoman Divacky   if (const UnaryOperator *CondUOp = dyn_cast<UnaryOperator>(Cond)) {
570f22ef01cSRoman Divacky     // br(!x, t, f) -> br(x, f, t)
571e580952dSDimitry Andric     if (CondUOp->getOpcode() == UO_LNot)
572f22ef01cSRoman Divacky       return EmitBranchOnBoolExpr(CondUOp->getSubExpr(), FalseBlock, TrueBlock);
573f22ef01cSRoman Divacky   }
574f22ef01cSRoman Divacky 
575f22ef01cSRoman Divacky   if (const ConditionalOperator *CondOp = dyn_cast<ConditionalOperator>(Cond)) {
576f22ef01cSRoman Divacky     // Handle ?: operator.
577f22ef01cSRoman Divacky 
578f22ef01cSRoman Divacky     // Just ignore GNU ?: extension.
579f22ef01cSRoman Divacky     if (CondOp->getLHS()) {
580f22ef01cSRoman Divacky       // br(c ? x : y, t, f) -> br(c, br(x, t, f), br(y, t, f))
581f22ef01cSRoman Divacky       llvm::BasicBlock *LHSBlock = createBasicBlock("cond.true");
582f22ef01cSRoman Divacky       llvm::BasicBlock *RHSBlock = createBasicBlock("cond.false");
5832754fe60SDimitry Andric 
5842754fe60SDimitry Andric       ConditionalEvaluation cond(*this);
585f22ef01cSRoman Divacky       EmitBranchOnBoolExpr(CondOp->getCond(), LHSBlock, RHSBlock);
5862754fe60SDimitry Andric 
5872754fe60SDimitry Andric       cond.begin(*this);
588f22ef01cSRoman Divacky       EmitBlock(LHSBlock);
589f22ef01cSRoman Divacky       EmitBranchOnBoolExpr(CondOp->getLHS(), TrueBlock, FalseBlock);
5902754fe60SDimitry Andric       cond.end(*this);
5912754fe60SDimitry Andric 
5922754fe60SDimitry Andric       cond.begin(*this);
593f22ef01cSRoman Divacky       EmitBlock(RHSBlock);
594f22ef01cSRoman Divacky       EmitBranchOnBoolExpr(CondOp->getRHS(), TrueBlock, FalseBlock);
5952754fe60SDimitry Andric       cond.end(*this);
5962754fe60SDimitry Andric 
597f22ef01cSRoman Divacky       return;
598f22ef01cSRoman Divacky     }
599f22ef01cSRoman Divacky   }
600f22ef01cSRoman Divacky 
601f22ef01cSRoman Divacky   // Emit the code with the fully general case.
602f22ef01cSRoman Divacky   llvm::Value *CondV = EvaluateExprAsBool(Cond);
603f22ef01cSRoman Divacky   Builder.CreateCondBr(CondV, TrueBlock, FalseBlock);
604f22ef01cSRoman Divacky }
605f22ef01cSRoman Divacky 
606f22ef01cSRoman Divacky /// ErrorUnsupported - Print out an error that codegen doesn't support the
607f22ef01cSRoman Divacky /// specified stmt yet.
608f22ef01cSRoman Divacky void CodeGenFunction::ErrorUnsupported(const Stmt *S, const char *Type,
609f22ef01cSRoman Divacky                                        bool OmitOnError) {
610f22ef01cSRoman Divacky   CGM.ErrorUnsupported(S, Type, OmitOnError);
611f22ef01cSRoman Divacky }
612f22ef01cSRoman Divacky 
6132754fe60SDimitry Andric /// emitNonZeroVLAInit - Emit the "zero" initialization of a
6142754fe60SDimitry Andric /// variable-length array whose elements have a non-zero bit-pattern.
6152754fe60SDimitry Andric ///
6162754fe60SDimitry Andric /// \param src - a char* pointing to the bit-pattern for a single
6172754fe60SDimitry Andric /// base element of the array
6182754fe60SDimitry Andric /// \param sizeInChars - the total size of the VLA, in chars
6192754fe60SDimitry Andric /// \param align - the total alignment of the VLA
6202754fe60SDimitry Andric static void emitNonZeroVLAInit(CodeGenFunction &CGF, QualType baseType,
6212754fe60SDimitry Andric                                llvm::Value *dest, llvm::Value *src,
6222754fe60SDimitry Andric                                llvm::Value *sizeInChars) {
6232754fe60SDimitry Andric   std::pair<CharUnits,CharUnits> baseSizeAndAlign
6242754fe60SDimitry Andric     = CGF.getContext().getTypeInfoInChars(baseType);
6252754fe60SDimitry Andric 
6262754fe60SDimitry Andric   CGBuilderTy &Builder = CGF.Builder;
6272754fe60SDimitry Andric 
6282754fe60SDimitry Andric   llvm::Value *baseSizeInChars
6292754fe60SDimitry Andric     = llvm::ConstantInt::get(CGF.IntPtrTy, baseSizeAndAlign.first.getQuantity());
6302754fe60SDimitry Andric 
6312754fe60SDimitry Andric   const llvm::Type *i8p = Builder.getInt8PtrTy();
6322754fe60SDimitry Andric 
6332754fe60SDimitry Andric   llvm::Value *begin = Builder.CreateBitCast(dest, i8p, "vla.begin");
6342754fe60SDimitry Andric   llvm::Value *end = Builder.CreateInBoundsGEP(dest, sizeInChars, "vla.end");
6352754fe60SDimitry Andric 
6362754fe60SDimitry Andric   llvm::BasicBlock *originBB = CGF.Builder.GetInsertBlock();
6372754fe60SDimitry Andric   llvm::BasicBlock *loopBB = CGF.createBasicBlock("vla-init.loop");
6382754fe60SDimitry Andric   llvm::BasicBlock *contBB = CGF.createBasicBlock("vla-init.cont");
6392754fe60SDimitry Andric 
6402754fe60SDimitry Andric   // Make a loop over the VLA.  C99 guarantees that the VLA element
6412754fe60SDimitry Andric   // count must be nonzero.
6422754fe60SDimitry Andric   CGF.EmitBlock(loopBB);
6432754fe60SDimitry Andric 
6443b0f4066SDimitry Andric   llvm::PHINode *cur = Builder.CreatePHI(i8p, 2, "vla.cur");
6452754fe60SDimitry Andric   cur->addIncoming(begin, originBB);
6462754fe60SDimitry Andric 
6472754fe60SDimitry Andric   // memcpy the individual element bit-pattern.
6482754fe60SDimitry Andric   Builder.CreateMemCpy(cur, src, baseSizeInChars,
6492754fe60SDimitry Andric                        baseSizeAndAlign.second.getQuantity(),
6502754fe60SDimitry Andric                        /*volatile*/ false);
6512754fe60SDimitry Andric 
6522754fe60SDimitry Andric   // Go to the next element.
6532754fe60SDimitry Andric   llvm::Value *next = Builder.CreateConstInBoundsGEP1_32(cur, 1, "vla.next");
6542754fe60SDimitry Andric 
6552754fe60SDimitry Andric   // Leave if that's the end of the VLA.
6562754fe60SDimitry Andric   llvm::Value *done = Builder.CreateICmpEQ(next, end, "vla-init.isdone");
6572754fe60SDimitry Andric   Builder.CreateCondBr(done, contBB, loopBB);
6582754fe60SDimitry Andric   cur->addIncoming(next, loopBB);
6592754fe60SDimitry Andric 
6602754fe60SDimitry Andric   CGF.EmitBlock(contBB);
6612754fe60SDimitry Andric }
6622754fe60SDimitry Andric 
663f22ef01cSRoman Divacky void
664f22ef01cSRoman Divacky CodeGenFunction::EmitNullInitialization(llvm::Value *DestPtr, QualType Ty) {
665f22ef01cSRoman Divacky   // Ignore empty classes in C++.
666f22ef01cSRoman Divacky   if (getContext().getLangOptions().CPlusPlus) {
667f22ef01cSRoman Divacky     if (const RecordType *RT = Ty->getAs<RecordType>()) {
668f22ef01cSRoman Divacky       if (cast<CXXRecordDecl>(RT->getDecl())->isEmpty())
669f22ef01cSRoman Divacky         return;
670f22ef01cSRoman Divacky     }
671f22ef01cSRoman Divacky   }
672f22ef01cSRoman Divacky 
673e580952dSDimitry Andric   // Cast the dest ptr to the appropriate i8 pointer type.
674e580952dSDimitry Andric   unsigned DestAS =
675e580952dSDimitry Andric     cast<llvm::PointerType>(DestPtr->getType())->getAddressSpace();
6762754fe60SDimitry Andric   const llvm::Type *BP = Builder.getInt8PtrTy(DestAS);
677f22ef01cSRoman Divacky   if (DestPtr->getType() != BP)
678f22ef01cSRoman Divacky     DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
679f22ef01cSRoman Divacky 
680f22ef01cSRoman Divacky   // Get size and alignment info for this aggregate.
6813b0f4066SDimitry Andric   std::pair<CharUnits, CharUnits> TypeInfo =
6823b0f4066SDimitry Andric     getContext().getTypeInfoInChars(Ty);
6833b0f4066SDimitry Andric   CharUnits Size = TypeInfo.first;
6843b0f4066SDimitry Andric   CharUnits Align = TypeInfo.second;
6852754fe60SDimitry Andric 
6862754fe60SDimitry Andric   llvm::Value *SizeVal;
6872754fe60SDimitry Andric   const VariableArrayType *vla;
688f22ef01cSRoman Divacky 
689f22ef01cSRoman Divacky   // Don't bother emitting a zero-byte memset.
6903b0f4066SDimitry Andric   if (Size.isZero()) {
6912754fe60SDimitry Andric     // But note that getTypeInfo returns 0 for a VLA.
6922754fe60SDimitry Andric     if (const VariableArrayType *vlaType =
6932754fe60SDimitry Andric           dyn_cast_or_null<VariableArrayType>(
6942754fe60SDimitry Andric                                           getContext().getAsArrayType(Ty))) {
6952754fe60SDimitry Andric       SizeVal = GetVLASize(vlaType);
6962754fe60SDimitry Andric       vla = vlaType;
6972754fe60SDimitry Andric     } else {
698f22ef01cSRoman Divacky       return;
6992754fe60SDimitry Andric     }
7002754fe60SDimitry Andric   } else {
7013b0f4066SDimitry Andric     SizeVal = llvm::ConstantInt::get(IntPtrTy, Size.getQuantity());
7022754fe60SDimitry Andric     vla = 0;
7032754fe60SDimitry Andric   }
704e580952dSDimitry Andric 
705e580952dSDimitry Andric   // If the type contains a pointer to data member we can't memset it to zero.
706e580952dSDimitry Andric   // Instead, create a null constant and copy it to the destination.
7072754fe60SDimitry Andric   // TODO: there are other patterns besides zero that we can usefully memset,
7082754fe60SDimitry Andric   // like -1, which happens to be the pattern used by member-pointers.
709e580952dSDimitry Andric   if (!CGM.getTypes().isZeroInitializable(Ty)) {
7102754fe60SDimitry Andric     // For a VLA, emit a single element, then splat that over the VLA.
7112754fe60SDimitry Andric     if (vla) Ty = getContext().getBaseElementType(vla);
7122754fe60SDimitry Andric 
713e580952dSDimitry Andric     llvm::Constant *NullConstant = CGM.EmitNullConstant(Ty);
714e580952dSDimitry Andric 
715e580952dSDimitry Andric     llvm::GlobalVariable *NullVariable =
716e580952dSDimitry Andric       new llvm::GlobalVariable(CGM.getModule(), NullConstant->getType(),
717e580952dSDimitry Andric                                /*isConstant=*/true,
718e580952dSDimitry Andric                                llvm::GlobalVariable::PrivateLinkage,
719e580952dSDimitry Andric                                NullConstant, llvm::Twine());
720e580952dSDimitry Andric     llvm::Value *SrcPtr =
721e580952dSDimitry Andric       Builder.CreateBitCast(NullVariable, Builder.getInt8PtrTy());
722e580952dSDimitry Andric 
7232754fe60SDimitry Andric     if (vla) return emitNonZeroVLAInit(*this, Ty, DestPtr, SrcPtr, SizeVal);
724e580952dSDimitry Andric 
725e580952dSDimitry Andric     // Get and call the appropriate llvm.memcpy overload.
7263b0f4066SDimitry Andric     Builder.CreateMemCpy(DestPtr, SrcPtr, SizeVal, Align.getQuantity(), false);
727e580952dSDimitry Andric     return;
728e580952dSDimitry Andric   }
729e580952dSDimitry Andric 
730e580952dSDimitry Andric   // Otherwise, just memset the whole thing to zero.  This is legal
731e580952dSDimitry Andric   // because in LLVM, all default initializers (other than the ones we just
732e580952dSDimitry Andric   // handled above) are guaranteed to have a bit pattern of all zeros.
7333b0f4066SDimitry Andric   Builder.CreateMemSet(DestPtr, Builder.getInt8(0), SizeVal,
7343b0f4066SDimitry Andric                        Align.getQuantity(), false);
735f22ef01cSRoman Divacky }
736f22ef01cSRoman Divacky 
7372754fe60SDimitry Andric llvm::BlockAddress *CodeGenFunction::GetAddrOfLabel(const LabelDecl *L) {
738f22ef01cSRoman Divacky   // Make sure that there is a block for the indirect goto.
739f22ef01cSRoman Divacky   if (IndirectBranch == 0)
740f22ef01cSRoman Divacky     GetIndirectGotoBlock();
741f22ef01cSRoman Divacky 
742e580952dSDimitry Andric   llvm::BasicBlock *BB = getJumpDestForLabel(L).getBlock();
743f22ef01cSRoman Divacky 
744f22ef01cSRoman Divacky   // Make sure the indirect branch includes all of the address-taken blocks.
745f22ef01cSRoman Divacky   IndirectBranch->addDestination(BB);
746f22ef01cSRoman Divacky   return llvm::BlockAddress::get(CurFn, BB);
747f22ef01cSRoman Divacky }
748f22ef01cSRoman Divacky 
749f22ef01cSRoman Divacky llvm::BasicBlock *CodeGenFunction::GetIndirectGotoBlock() {
750f22ef01cSRoman Divacky   // If we already made the indirect branch for indirect goto, return its block.
751f22ef01cSRoman Divacky   if (IndirectBranch) return IndirectBranch->getParent();
752f22ef01cSRoman Divacky 
753f22ef01cSRoman Divacky   CGBuilderTy TmpBuilder(createBasicBlock("indirectgoto"));
754f22ef01cSRoman Divacky 
755f22ef01cSRoman Divacky   // Create the PHI node that indirect gotos will add entries to.
7563b0f4066SDimitry Andric   llvm::Value *DestVal = TmpBuilder.CreatePHI(Int8PtrTy, 0,
7573b0f4066SDimitry Andric                                               "indirect.goto.dest");
758f22ef01cSRoman Divacky 
759f22ef01cSRoman Divacky   // Create the indirect branch instruction.
760f22ef01cSRoman Divacky   IndirectBranch = TmpBuilder.CreateIndirectBr(DestVal);
761f22ef01cSRoman Divacky   return IndirectBranch->getParent();
762f22ef01cSRoman Divacky }
763f22ef01cSRoman Divacky 
764f22ef01cSRoman Divacky llvm::Value *CodeGenFunction::GetVLASize(const VariableArrayType *VAT) {
765f22ef01cSRoman Divacky   llvm::Value *&SizeEntry = VLASizeMap[VAT->getSizeExpr()];
766f22ef01cSRoman Divacky 
767f22ef01cSRoman Divacky   assert(SizeEntry && "Did not emit size for type");
768f22ef01cSRoman Divacky   return SizeEntry;
769f22ef01cSRoman Divacky }
770f22ef01cSRoman Divacky 
771f22ef01cSRoman Divacky llvm::Value *CodeGenFunction::EmitVLASize(QualType Ty) {
772f22ef01cSRoman Divacky   assert(Ty->isVariablyModifiedType() &&
773f22ef01cSRoman Divacky          "Must pass variably modified type to EmitVLASizes!");
774f22ef01cSRoman Divacky 
775f22ef01cSRoman Divacky   EnsureInsertPoint();
776f22ef01cSRoman Divacky 
777f22ef01cSRoman Divacky   if (const VariableArrayType *VAT = getContext().getAsVariableArrayType(Ty)) {
7782754fe60SDimitry Andric     // unknown size indication requires no size computation.
7792754fe60SDimitry Andric     if (!VAT->getSizeExpr())
7802754fe60SDimitry Andric       return 0;
781f22ef01cSRoman Divacky     llvm::Value *&SizeEntry = VLASizeMap[VAT->getSizeExpr()];
782f22ef01cSRoman Divacky 
783f22ef01cSRoman Divacky     if (!SizeEntry) {
784f22ef01cSRoman Divacky       const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
785f22ef01cSRoman Divacky 
786f22ef01cSRoman Divacky       // Get the element size;
787f22ef01cSRoman Divacky       QualType ElemTy = VAT->getElementType();
788f22ef01cSRoman Divacky       llvm::Value *ElemSize;
789f22ef01cSRoman Divacky       if (ElemTy->isVariableArrayType())
790f22ef01cSRoman Divacky         ElemSize = EmitVLASize(ElemTy);
791f22ef01cSRoman Divacky       else
792f22ef01cSRoman Divacky         ElemSize = llvm::ConstantInt::get(SizeTy,
793f22ef01cSRoman Divacky             getContext().getTypeSizeInChars(ElemTy).getQuantity());
794f22ef01cSRoman Divacky 
795f22ef01cSRoman Divacky       llvm::Value *NumElements = EmitScalarExpr(VAT->getSizeExpr());
796f22ef01cSRoman Divacky       NumElements = Builder.CreateIntCast(NumElements, SizeTy, false, "tmp");
797f22ef01cSRoman Divacky 
798f22ef01cSRoman Divacky       SizeEntry = Builder.CreateMul(ElemSize, NumElements);
799f22ef01cSRoman Divacky     }
800f22ef01cSRoman Divacky 
801f22ef01cSRoman Divacky     return SizeEntry;
802f22ef01cSRoman Divacky   }
803f22ef01cSRoman Divacky 
804f22ef01cSRoman Divacky   if (const ArrayType *AT = dyn_cast<ArrayType>(Ty)) {
805f22ef01cSRoman Divacky     EmitVLASize(AT->getElementType());
806f22ef01cSRoman Divacky     return 0;
807f22ef01cSRoman Divacky   }
808f22ef01cSRoman Divacky 
8092754fe60SDimitry Andric   if (const ParenType *PT = dyn_cast<ParenType>(Ty)) {
8102754fe60SDimitry Andric     EmitVLASize(PT->getInnerType());
8112754fe60SDimitry Andric     return 0;
8122754fe60SDimitry Andric   }
8132754fe60SDimitry Andric 
814f22ef01cSRoman Divacky   const PointerType *PT = Ty->getAs<PointerType>();
815f22ef01cSRoman Divacky   assert(PT && "unknown VM type!");
816f22ef01cSRoman Divacky   EmitVLASize(PT->getPointeeType());
817f22ef01cSRoman Divacky   return 0;
818f22ef01cSRoman Divacky }
819f22ef01cSRoman Divacky 
820f22ef01cSRoman Divacky llvm::Value* CodeGenFunction::EmitVAListRef(const Expr* E) {
8212754fe60SDimitry Andric   if (getContext().getBuiltinVaListType()->isArrayType())
822f22ef01cSRoman Divacky     return EmitScalarExpr(E);
823f22ef01cSRoman Divacky   return EmitLValue(E).getAddress();
824f22ef01cSRoman Divacky }
825f22ef01cSRoman Divacky 
826e580952dSDimitry Andric void CodeGenFunction::EmitDeclRefExprDbgValue(const DeclRefExpr *E,
8272754fe60SDimitry Andric                                               llvm::Constant *Init) {
828e580952dSDimitry Andric   assert (Init && "Invalid DeclRefExpr initializer!");
829e580952dSDimitry Andric   if (CGDebugInfo *Dbg = getDebugInfo())
8302754fe60SDimitry Andric     Dbg->EmitGlobalVariable(E->getDecl(), Init);
8312754fe60SDimitry Andric }
8322754fe60SDimitry Andric 
8332754fe60SDimitry Andric CodeGenFunction::PeepholeProtection
8342754fe60SDimitry Andric CodeGenFunction::protectFromPeepholes(RValue rvalue) {
8352754fe60SDimitry Andric   // At the moment, the only aggressive peephole we do in IR gen
8362754fe60SDimitry Andric   // is trunc(zext) folding, but if we add more, we can easily
8372754fe60SDimitry Andric   // extend this protection.
8382754fe60SDimitry Andric 
8392754fe60SDimitry Andric   if (!rvalue.isScalar()) return PeepholeProtection();
8402754fe60SDimitry Andric   llvm::Value *value = rvalue.getScalarVal();
8412754fe60SDimitry Andric   if (!isa<llvm::ZExtInst>(value)) return PeepholeProtection();
8422754fe60SDimitry Andric 
8432754fe60SDimitry Andric   // Just make an extra bitcast.
8442754fe60SDimitry Andric   assert(HaveInsertPoint());
8452754fe60SDimitry Andric   llvm::Instruction *inst = new llvm::BitCastInst(value, value->getType(), "",
8462754fe60SDimitry Andric                                                   Builder.GetInsertBlock());
8472754fe60SDimitry Andric 
8482754fe60SDimitry Andric   PeepholeProtection protection;
8492754fe60SDimitry Andric   protection.Inst = inst;
8502754fe60SDimitry Andric   return protection;
8512754fe60SDimitry Andric }
8522754fe60SDimitry Andric 
8532754fe60SDimitry Andric void CodeGenFunction::unprotectFromPeepholes(PeepholeProtection protection) {
8542754fe60SDimitry Andric   if (!protection.Inst) return;
8552754fe60SDimitry Andric 
8562754fe60SDimitry Andric   // In theory, we could try to duplicate the peepholes now, but whatever.
8572754fe60SDimitry Andric   protection.Inst->eraseFromParent();
858e580952dSDimitry Andric }
859