blob: dfa212460bad343b77061d8757e64bf9a1732d39 [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +00001//===--- CGStmt.cpp - Emit LLVM Code from Statements ----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner0bc735f2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Reid Spencer5f016e22007-07-11 17:01:13 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This contains code to emit Stmt nodes as LLVM code.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CodeGenFunction.h"
15#include "clang/AST/AST.h"
16#include "llvm/Constants.h"
17#include "llvm/DerivedTypes.h"
18#include "llvm/Function.h"
19using namespace clang;
20using namespace CodeGen;
21
22//===----------------------------------------------------------------------===//
23// Statement Emission
24//===----------------------------------------------------------------------===//
25
26void CodeGenFunction::EmitStmt(const Stmt *S) {
27 assert(S && "Null statement?");
28
29 switch (S->getStmtClass()) {
30 default:
Chris Lattner1e4d21e2007-08-26 22:58:05 +000031 // Must be an expression in a stmt context. Emit the value (to get
32 // side-effects) and ignore the result.
Reid Spencer5f016e22007-07-11 17:01:13 +000033 if (const Expr *E = dyn_cast<Expr>(S)) {
Chris Lattner1e4d21e2007-08-26 22:58:05 +000034 if (!hasAggregateLLVMType(E->getType()))
35 EmitScalarExpr(E);
36 else if (E->getType()->isComplexType())
37 EmitComplexExpr(E);
38 else
39 EmitAggExpr(E, 0, false);
Reid Spencer5f016e22007-07-11 17:01:13 +000040 } else {
Chris Lattnerdc4d2802007-12-02 01:49:16 +000041 WarnUnsupported(S, "statement");
Reid Spencer5f016e22007-07-11 17:01:13 +000042 }
43 break;
44 case Stmt::NullStmtClass: break;
45 case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break;
46 case Stmt::LabelStmtClass: EmitLabelStmt(cast<LabelStmt>(*S)); break;
47 case Stmt::GotoStmtClass: EmitGotoStmt(cast<GotoStmt>(*S)); break;
48
49 case Stmt::IfStmtClass: EmitIfStmt(cast<IfStmt>(*S)); break;
50 case Stmt::WhileStmtClass: EmitWhileStmt(cast<WhileStmt>(*S)); break;
51 case Stmt::DoStmtClass: EmitDoStmt(cast<DoStmt>(*S)); break;
52 case Stmt::ForStmtClass: EmitForStmt(cast<ForStmt>(*S)); break;
53
54 case Stmt::ReturnStmtClass: EmitReturnStmt(cast<ReturnStmt>(*S)); break;
55 case Stmt::DeclStmtClass: EmitDeclStmt(cast<DeclStmt>(*S)); break;
Chris Lattnerda138702007-07-16 21:28:45 +000056
57 case Stmt::BreakStmtClass: EmitBreakStmt(); break;
58 case Stmt::ContinueStmtClass: EmitContinueStmt(); break;
Devang Patel51b09f22007-10-04 23:45:31 +000059 case Stmt::SwitchStmtClass: EmitSwitchStmt(cast<SwitchStmt>(*S)); break;
60 case Stmt::DefaultStmtClass: EmitDefaultStmt(cast<DefaultStmt>(*S)); break;
61 case Stmt::CaseStmtClass: EmitCaseStmt(cast<CaseStmt>(*S)); break;
Reid Spencer5f016e22007-07-11 17:01:13 +000062 }
63}
64
Chris Lattner33793202007-08-31 22:09:40 +000065/// EmitCompoundStmt - Emit a compound statement {..} node. If GetLast is true,
66/// this captures the expression result of the last sub-statement and returns it
67/// (for use by the statement expression extension).
Chris Lattner9b655512007-08-31 22:49:20 +000068RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast,
69 llvm::Value *AggLoc, bool isAggVol) {
Reid Spencer5f016e22007-07-11 17:01:13 +000070 // FIXME: handle vla's etc.
Chris Lattner33793202007-08-31 22:09:40 +000071 if (S.body_empty() || !isa<Expr>(S.body_back())) GetLast = false;
Reid Spencer5f016e22007-07-11 17:01:13 +000072
Chris Lattner33793202007-08-31 22:09:40 +000073 for (CompoundStmt::const_body_iterator I = S.body_begin(),
74 E = S.body_end()-GetLast; I != E; ++I)
Reid Spencer5f016e22007-07-11 17:01:13 +000075 EmitStmt(*I);
Chris Lattner33793202007-08-31 22:09:40 +000076
77
78 if (!GetLast)
79 return RValue::get(0);
Chris Lattner9b655512007-08-31 22:49:20 +000080
81 return EmitAnyExpr(cast<Expr>(S.body_back()), AggLoc);
Reid Spencer5f016e22007-07-11 17:01:13 +000082}
83
84void CodeGenFunction::EmitBlock(llvm::BasicBlock *BB) {
85 // Emit a branch from this block to the next one if this was a real block. If
86 // this was just a fall-through block after a terminator, don't emit it.
87 llvm::BasicBlock *LastBB = Builder.GetInsertBlock();
88
89 if (LastBB->getTerminator()) {
90 // If the previous block is already terminated, don't touch it.
91 } else if (LastBB->empty() && LastBB->getValueName() == 0) {
92 // If the last block was an empty placeholder, remove it now.
93 // TODO: cache and reuse these.
94 Builder.GetInsertBlock()->eraseFromParent();
95 } else {
96 // Otherwise, create a fall-through branch.
97 Builder.CreateBr(BB);
98 }
99 CurFn->getBasicBlockList().push_back(BB);
100 Builder.SetInsertPoint(BB);
101}
102
103void CodeGenFunction::EmitLabelStmt(const LabelStmt &S) {
104 llvm::BasicBlock *NextBB = getBasicBlockForLabel(&S);
105
106 EmitBlock(NextBB);
107 EmitStmt(S.getSubStmt());
108}
109
110void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) {
111 Builder.CreateBr(getBasicBlockForLabel(S.getLabel()));
112
113 // Emit a block after the branch so that dead code after a goto has some place
114 // to go.
115 Builder.SetInsertPoint(new llvm::BasicBlock("", CurFn));
116}
117
118void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
119 // C99 6.8.4.1: The first substatement is executed if the expression compares
120 // unequal to 0. The condition must be a scalar type.
121 llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
122
123 llvm::BasicBlock *ContBlock = new llvm::BasicBlock("ifend");
124 llvm::BasicBlock *ThenBlock = new llvm::BasicBlock("ifthen");
125 llvm::BasicBlock *ElseBlock = ContBlock;
126
127 if (S.getElse())
128 ElseBlock = new llvm::BasicBlock("ifelse");
129
130 // Insert the conditional branch.
131 Builder.CreateCondBr(BoolCondVal, ThenBlock, ElseBlock);
132
133 // Emit the 'then' code.
134 EmitBlock(ThenBlock);
135 EmitStmt(S.getThen());
Devang Pateld9363c32007-09-28 21:49:18 +0000136 llvm::BasicBlock *BB = Builder.GetInsertBlock();
137 if (isDummyBlock(BB)) {
138 BB->eraseFromParent();
139 Builder.SetInsertPoint(ThenBlock);
140 }
141 else
142 Builder.CreateBr(ContBlock);
Reid Spencer5f016e22007-07-11 17:01:13 +0000143
144 // Emit the 'else' code if present.
145 if (const Stmt *Else = S.getElse()) {
146 EmitBlock(ElseBlock);
147 EmitStmt(Else);
Devang Pateld9363c32007-09-28 21:49:18 +0000148 llvm::BasicBlock *BB = Builder.GetInsertBlock();
149 if (isDummyBlock(BB)) {
150 BB->eraseFromParent();
151 Builder.SetInsertPoint(ElseBlock);
152 }
153 else
154 Builder.CreateBr(ContBlock);
Reid Spencer5f016e22007-07-11 17:01:13 +0000155 }
156
157 // Emit the continuation block for code after the if.
158 EmitBlock(ContBlock);
159}
160
161void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000162 // Emit the header for the loop, insert it, which will create an uncond br to
163 // it.
164 llvm::BasicBlock *LoopHeader = new llvm::BasicBlock("whilecond");
165 EmitBlock(LoopHeader);
166
167 // Evaluate the conditional in the while header. C99 6.8.5.1: The evaluation
168 // of the controlling expression takes place before each execution of the loop
169 // body.
170 llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
Devang Patel2c30d8f2007-10-09 20:51:27 +0000171
172 // while(1) is common, avoid extra exit blocks. Be sure
Reid Spencer5f016e22007-07-11 17:01:13 +0000173 // to correctly handle break/continue though.
Devang Patel2c30d8f2007-10-09 20:51:27 +0000174 bool EmitBoolCondBranch = true;
175 if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal))
176 if (C->isOne())
177 EmitBoolCondBranch = false;
Reid Spencer5f016e22007-07-11 17:01:13 +0000178
179 // Create an exit block for when the condition fails, create a block for the
180 // body of the loop.
181 llvm::BasicBlock *ExitBlock = new llvm::BasicBlock("whileexit");
182 llvm::BasicBlock *LoopBody = new llvm::BasicBlock("whilebody");
183
184 // As long as the condition is true, go to the loop body.
Devang Patel2c30d8f2007-10-09 20:51:27 +0000185 if (EmitBoolCondBranch)
186 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
Chris Lattnerda138702007-07-16 21:28:45 +0000187
188 // Store the blocks to use for break and continue.
189 BreakContinueStack.push_back(BreakContinue(ExitBlock, LoopHeader));
Reid Spencer5f016e22007-07-11 17:01:13 +0000190
191 // Emit the loop body.
192 EmitBlock(LoopBody);
193 EmitStmt(S.getBody());
Chris Lattnerda138702007-07-16 21:28:45 +0000194
195 BreakContinueStack.pop_back();
Reid Spencer5f016e22007-07-11 17:01:13 +0000196
197 // Cycle to the condition.
198 Builder.CreateBr(LoopHeader);
199
200 // Emit the exit block.
201 EmitBlock(ExitBlock);
Devang Patel2c30d8f2007-10-09 20:51:27 +0000202
203 // If LoopHeader is a simple forwarding block then eliminate it.
204 if (!EmitBoolCondBranch
205 && &LoopHeader->front() == LoopHeader->getTerminator()) {
206 LoopHeader->replaceAllUsesWith(LoopBody);
207 LoopHeader->getTerminator()->eraseFromParent();
208 LoopHeader->eraseFromParent();
209 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000210}
211
212void CodeGenFunction::EmitDoStmt(const DoStmt &S) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000213 // Emit the body for the loop, insert it, which will create an uncond br to
214 // it.
215 llvm::BasicBlock *LoopBody = new llvm::BasicBlock("dobody");
216 llvm::BasicBlock *AfterDo = new llvm::BasicBlock("afterdo");
217 EmitBlock(LoopBody);
Chris Lattnerda138702007-07-16 21:28:45 +0000218
219 llvm::BasicBlock *DoCond = new llvm::BasicBlock("docond");
220
221 // Store the blocks to use for break and continue.
222 BreakContinueStack.push_back(BreakContinue(AfterDo, DoCond));
Reid Spencer5f016e22007-07-11 17:01:13 +0000223
224 // Emit the body of the loop into the block.
225 EmitStmt(S.getBody());
226
Chris Lattnerda138702007-07-16 21:28:45 +0000227 BreakContinueStack.pop_back();
228
229 EmitBlock(DoCond);
230
Reid Spencer5f016e22007-07-11 17:01:13 +0000231 // C99 6.8.5.2: "The evaluation of the controlling expression takes place
232 // after each execution of the loop body."
233
234 // Evaluate the conditional in the while header.
235 // C99 6.8.5p2/p4: The first substatement is executed if the expression
236 // compares unequal to 0. The condition must be a scalar type.
237 llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
Devang Patel05f6e6b2007-10-09 20:33:39 +0000238
239 // "do {} while (0)" is common in macros, avoid extra blocks. Be sure
240 // to correctly handle break/continue though.
241 bool EmitBoolCondBranch = true;
242 if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal))
243 if (C->isZero())
244 EmitBoolCondBranch = false;
245
Reid Spencer5f016e22007-07-11 17:01:13 +0000246 // As long as the condition is true, iterate the loop.
Devang Patel05f6e6b2007-10-09 20:33:39 +0000247 if (EmitBoolCondBranch)
248 Builder.CreateCondBr(BoolCondVal, LoopBody, AfterDo);
Reid Spencer5f016e22007-07-11 17:01:13 +0000249
250 // Emit the exit block.
251 EmitBlock(AfterDo);
Devang Patel05f6e6b2007-10-09 20:33:39 +0000252
253 // If DoCond is a simple forwarding block then eliminate it.
254 if (!EmitBoolCondBranch && &DoCond->front() == DoCond->getTerminator()) {
255 DoCond->replaceAllUsesWith(AfterDo);
256 DoCond->getTerminator()->eraseFromParent();
257 DoCond->eraseFromParent();
258 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000259}
260
261void CodeGenFunction::EmitForStmt(const ForStmt &S) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000262 // FIXME: What do we do if the increment (f.e.) contains a stmt expression,
263 // which contains a continue/break?
Chris Lattnerda138702007-07-16 21:28:45 +0000264 // TODO: We could keep track of whether the loop body contains any
265 // break/continue statements and not create unnecessary blocks (like
266 // "afterfor" for a condless loop) if it doesn't.
267
Reid Spencer5f016e22007-07-11 17:01:13 +0000268 // Evaluate the first part before the loop.
269 if (S.getInit())
270 EmitStmt(S.getInit());
271
272 // Start the loop with a block that tests the condition.
273 llvm::BasicBlock *CondBlock = new llvm::BasicBlock("forcond");
Chris Lattnerda138702007-07-16 21:28:45 +0000274 llvm::BasicBlock *AfterFor = new llvm::BasicBlock("afterfor");
275
Reid Spencer5f016e22007-07-11 17:01:13 +0000276 EmitBlock(CondBlock);
277
278 // Evaluate the condition if present. If not, treat it as a non-zero-constant
279 // according to 6.8.5.3p2, aka, true.
280 if (S.getCond()) {
281 // C99 6.8.5p2/p4: The first substatement is executed if the expression
282 // compares unequal to 0. The condition must be a scalar type.
283 llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
284
285 // As long as the condition is true, iterate the loop.
286 llvm::BasicBlock *ForBody = new llvm::BasicBlock("forbody");
Reid Spencer5f016e22007-07-11 17:01:13 +0000287 Builder.CreateCondBr(BoolCondVal, ForBody, AfterFor);
288 EmitBlock(ForBody);
289 } else {
290 // Treat it as a non-zero constant. Don't even create a new block for the
291 // body, just fall into it.
292 }
293
Chris Lattnerda138702007-07-16 21:28:45 +0000294 // If the for loop doesn't have an increment we can just use the
295 // condition as the continue block.
296 llvm::BasicBlock *ContinueBlock;
297 if (S.getInc())
298 ContinueBlock = new llvm::BasicBlock("forinc");
299 else
300 ContinueBlock = CondBlock;
301
302 // Store the blocks to use for break and continue.
303 BreakContinueStack.push_back(BreakContinue(AfterFor, ContinueBlock));
304
Reid Spencer5f016e22007-07-11 17:01:13 +0000305 // If the condition is true, execute the body of the for stmt.
306 EmitStmt(S.getBody());
Chris Lattnerda138702007-07-16 21:28:45 +0000307
308 BreakContinueStack.pop_back();
309
310 if (S.getInc())
311 EmitBlock(ContinueBlock);
Reid Spencer5f016e22007-07-11 17:01:13 +0000312
313 // If there is an increment, emit it next.
314 if (S.getInc())
Chris Lattner883f6a72007-08-11 00:04:45 +0000315 EmitStmt(S.getInc());
Reid Spencer5f016e22007-07-11 17:01:13 +0000316
317 // Finally, branch back up to the condition for the next iteration.
318 Builder.CreateBr(CondBlock);
319
Chris Lattnerda138702007-07-16 21:28:45 +0000320 // Emit the fall-through block.
321 EmitBlock(AfterFor);
Reid Spencer5f016e22007-07-11 17:01:13 +0000322}
323
324/// EmitReturnStmt - Note that due to GCC extensions, this can have an operand
325/// if the function returns void, or may be missing one if the function returns
326/// non-void. Fun stuff :).
327void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000328 // Emit the result value, even if unused, to evalute the side effects.
329 const Expr *RV = S.getRetValue();
Chris Lattner4b0029d2007-08-26 07:14:44 +0000330
Reid Spencer5f016e22007-07-11 17:01:13 +0000331 QualType FnRetTy = CurFuncDecl->getType().getCanonicalType();
332 FnRetTy = cast<FunctionType>(FnRetTy)->getResultType();
333
334 if (FnRetTy->isVoidType()) {
Chris Lattner4b0029d2007-08-26 07:14:44 +0000335 // If the function returns void, emit ret void.
Reid Spencer5f016e22007-07-11 17:01:13 +0000336 Builder.CreateRetVoid();
337 } else if (RV == 0) {
Chris Lattner4b0029d2007-08-26 07:14:44 +0000338 // Handle "return;" in a function that returns a value.
Reid Spencer5f016e22007-07-11 17:01:13 +0000339 const llvm::Type *RetTy = CurFn->getFunctionType()->getReturnType();
340 if (RetTy == llvm::Type::VoidTy)
341 Builder.CreateRetVoid(); // struct return etc.
342 else
343 Builder.CreateRet(llvm::UndefValue::get(RetTy));
Chris Lattner4b0029d2007-08-26 07:14:44 +0000344 } else if (!hasAggregateLLVMType(RV->getType())) {
345 Builder.CreateRet(EmitScalarExpr(RV));
346 } else if (RV->getType()->isComplexType()) {
347 llvm::Value *SRetPtr = CurFn->arg_begin();
Chris Lattner190dbe22007-08-26 16:22:13 +0000348 EmitComplexExprIntoAddr(RV, SRetPtr, false);
Reid Spencer5f016e22007-07-11 17:01:13 +0000349 } else {
Chris Lattner4b0029d2007-08-26 07:14:44 +0000350 llvm::Value *SRetPtr = CurFn->arg_begin();
351 EmitAggExpr(RV, SRetPtr, false);
Reid Spencer5f016e22007-07-11 17:01:13 +0000352 }
353
354 // Emit a block after the branch so that dead code after a return has some
355 // place to go.
356 EmitBlock(new llvm::BasicBlock());
357}
358
359void CodeGenFunction::EmitDeclStmt(const DeclStmt &S) {
Steve Naroff94745042007-09-13 23:52:58 +0000360 for (const ScopedDecl *Decl = S.getDecl(); Decl;
361 Decl = Decl->getNextDeclarator())
Reid Spencer5f016e22007-07-11 17:01:13 +0000362 EmitDecl(*Decl);
Chris Lattner6fa5f092007-07-12 15:43:07 +0000363}
Chris Lattnerda138702007-07-16 21:28:45 +0000364
365void CodeGenFunction::EmitBreakStmt() {
366 assert(!BreakContinueStack.empty() && "break stmt not in a loop or switch!");
367
368 llvm::BasicBlock *Block = BreakContinueStack.back().BreakBlock;
369 Builder.CreateBr(Block);
370 EmitBlock(new llvm::BasicBlock());
371}
372
373void CodeGenFunction::EmitContinueStmt() {
374 assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
375
376 llvm::BasicBlock *Block = BreakContinueStack.back().ContinueBlock;
377 Builder.CreateBr(Block);
378 EmitBlock(new llvm::BasicBlock());
379}
Devang Patel51b09f22007-10-04 23:45:31 +0000380
Devang Patelc049e4f2007-10-08 20:57:48 +0000381/// EmitCaseStmtRange - If case statement range is not too big then
382/// add multiple cases to switch instruction, one for each value within
383/// the range. If range is too big then emit "if" condition check.
384void CodeGenFunction::EmitCaseStmtRange(const CaseStmt &S) {
385 assert (S.getRHS() && "Unexpected RHS value in CaseStmt");
386
387 const Expr *L = S.getLHS();
388 const Expr *R = S.getRHS();
389 llvm::ConstantInt *LV = cast<llvm::ConstantInt>(EmitScalarExpr(L));
390 llvm::ConstantInt *RV = cast<llvm::ConstantInt>(EmitScalarExpr(R));
391 llvm::APInt LHS = LV->getValue();
Devang Patel00ee4e42007-10-09 17:10:59 +0000392 const llvm::APInt &RHS = RV->getValue();
Devang Patelc049e4f2007-10-08 20:57:48 +0000393
394 llvm::APInt Range = RHS - LHS;
395 if (Range.ult(llvm::APInt(Range.getBitWidth(), 64))) {
396 // Range is small enough to add multiple switch instruction cases.
397 StartBlock("sw.bb");
398 llvm::BasicBlock *CaseDest = Builder.GetInsertBlock();
399 SwitchInsn->addCase(LV, CaseDest);
Devang Patel2d79d0f2007-10-05 20:54:07 +0000400 LHS++;
401 while (LHS != RHS) {
402 SwitchInsn->addCase(llvm::ConstantInt::get(LHS), CaseDest);
403 LHS++;
404 }
Devang Patelc049e4f2007-10-08 20:57:48 +0000405 SwitchInsn->addCase(RV, CaseDest);
406 EmitStmt(S.getSubStmt());
407 return;
408 }
409
410 // The range is too big. Emit "if" condition.
411 llvm::BasicBlock *FalseDest = NULL;
412 llvm::BasicBlock *CaseDest = new llvm::BasicBlock("sw.bb");
Devang Patel2d79d0f2007-10-05 20:54:07 +0000413
Devang Patelc049e4f2007-10-08 20:57:48 +0000414 // If we have already seen one case statement range for this switch
415 // instruction then piggy-back otherwise use default block as false
416 // destination.
417 if (CaseRangeBlock)
418 FalseDest = CaseRangeBlock;
419 else
420 FalseDest = SwitchInsn->getDefaultDest();
421
422 // Start new block to hold case statement range check instructions.
423 StartBlock("case.range");
424 CaseRangeBlock = Builder.GetInsertBlock();
425
426 // Emit range check.
427 llvm::Value *Diff =
428 Builder.CreateSub(SwitchInsn->getCondition(), LV, "tmp");
429 llvm::Value *Cond =
430 Builder.CreateICmpULE(Diff, llvm::ConstantInt::get(Range), "tmp");
431 Builder.CreateCondBr(Cond, CaseDest, FalseDest);
432
433 // Now emit case statement body.
434 EmitBlock(CaseDest);
435 EmitStmt(S.getSubStmt());
436}
437
438void CodeGenFunction::EmitCaseStmt(const CaseStmt &S) {
439 if (S.getRHS()) {
440 EmitCaseStmtRange(S);
441 return;
442 }
443
444 StartBlock("sw.bb");
445 llvm::BasicBlock *CaseDest = Builder.GetInsertBlock();
Chris Lattnerc69a5812007-11-30 17:44:57 +0000446 llvm::APSInt CaseVal(32);
447 S.getLHS()->isIntegerConstantExpr(CaseVal, getContext());
448 llvm::ConstantInt *LV = llvm::ConstantInt::get(CaseVal);
Devang Patelc049e4f2007-10-08 20:57:48 +0000449 SwitchInsn->addCase(LV, CaseDest);
Devang Patel51b09f22007-10-04 23:45:31 +0000450 EmitStmt(S.getSubStmt());
451}
452
453void CodeGenFunction::EmitDefaultStmt(const DefaultStmt &S) {
454 StartBlock("sw.default");
455 // Current insert block is the default destination.
456 SwitchInsn->setSuccessor(0, Builder.GetInsertBlock());
457 EmitStmt(S.getSubStmt());
458}
459
460void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {
461 llvm::Value *CondV = EmitScalarExpr(S.getCond());
462
463 // Handle nested switch statements.
464 llvm::SwitchInst *SavedSwitchInsn = SwitchInsn;
Devang Patelc049e4f2007-10-08 20:57:48 +0000465 llvm::BasicBlock *SavedCRBlock = CaseRangeBlock;
466 CaseRangeBlock = NULL;
Devang Patel51b09f22007-10-04 23:45:31 +0000467
468 // Create basic block to hold stuff that comes after switch statement.
469 // Initially use it to hold DefaultStmt.
Chris Lattner1438b492007-12-01 05:27:33 +0000470 llvm::BasicBlock *NextBlock = new llvm::BasicBlock("after.sw");
Devang Patel51b09f22007-10-04 23:45:31 +0000471 SwitchInsn = Builder.CreateSwitch(CondV, NextBlock);
472
Devang Patele9b8c0a2007-10-30 20:59:40 +0000473 // All break statements jump to NextBlock. If BreakContinueStack is non empty
474 // then reuse last ContinueBlock.
Devang Patel51b09f22007-10-04 23:45:31 +0000475 llvm::BasicBlock *ContinueBlock = NULL;
476 if (!BreakContinueStack.empty())
477 ContinueBlock = BreakContinueStack.back().ContinueBlock;
478 BreakContinueStack.push_back(BreakContinue(NextBlock, ContinueBlock));
479
480 // Emit switch body.
481 EmitStmt(S.getBody());
482 BreakContinueStack.pop_back();
483
Devang Patelc049e4f2007-10-08 20:57:48 +0000484 // If one or more case statement range is seen then use CaseRangeBlock
485 // as the default block. False edge of CaseRangeBlock will lead to
486 // original default block.
487 if (CaseRangeBlock)
488 SwitchInsn->setSuccessor(0, CaseRangeBlock);
489
Devang Patel51b09f22007-10-04 23:45:31 +0000490 // Prune insert block if it is dummy.
491 llvm::BasicBlock *BB = Builder.GetInsertBlock();
492 if (isDummyBlock(BB))
493 BB->eraseFromParent();
Chris Lattner1438b492007-12-01 05:27:33 +0000494 else // Otherwise, branch to continuation.
495 Builder.CreateBr(NextBlock);
Devang Patel51b09f22007-10-04 23:45:31 +0000496
497 // Place NextBlock as the new insert point.
Chris Lattner1438b492007-12-01 05:27:33 +0000498 CurFn->getBasicBlockList().push_back(NextBlock);
Devang Patel51b09f22007-10-04 23:45:31 +0000499 Builder.SetInsertPoint(NextBlock);
500 SwitchInsn = SavedSwitchInsn;
Devang Patelc049e4f2007-10-08 20:57:48 +0000501 CaseRangeBlock = SavedCRBlock;
Devang Patel51b09f22007-10-04 23:45:31 +0000502}