blob: f1f915e7c19cd73341e858e4b0883a9d9920de34 [file] [log] [blame]
Chris Lattner4b009652007-07-25 00:24:17 +00001//===--- CGStmt.cpp - Emit LLVM Code from Statements ----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
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 Lattner35055b82007-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.
Chris Lattner4b009652007-07-25 00:24:17 +000033 if (const Expr *E = dyn_cast<Expr>(S)) {
Chris Lattner35055b82007-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);
Chris Lattner4b009652007-07-25 00:24:17 +000040 } else {
41 printf("Unimplemented stmt!\n");
Chris Lattner1aef6212007-09-13 01:17:29 +000042 S->dump(getContext().SourceMgr);
Chris Lattner4b009652007-07-25 00:24:17 +000043 }
44 break;
45 case Stmt::NullStmtClass: break;
46 case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break;
47 case Stmt::LabelStmtClass: EmitLabelStmt(cast<LabelStmt>(*S)); break;
48 case Stmt::GotoStmtClass: EmitGotoStmt(cast<GotoStmt>(*S)); break;
49
50 case Stmt::IfStmtClass: EmitIfStmt(cast<IfStmt>(*S)); break;
51 case Stmt::WhileStmtClass: EmitWhileStmt(cast<WhileStmt>(*S)); break;
52 case Stmt::DoStmtClass: EmitDoStmt(cast<DoStmt>(*S)); break;
53 case Stmt::ForStmtClass: EmitForStmt(cast<ForStmt>(*S)); break;
54
55 case Stmt::ReturnStmtClass: EmitReturnStmt(cast<ReturnStmt>(*S)); break;
56 case Stmt::DeclStmtClass: EmitDeclStmt(cast<DeclStmt>(*S)); break;
57
58 case Stmt::BreakStmtClass: EmitBreakStmt(); break;
59 case Stmt::ContinueStmtClass: EmitContinueStmt(); break;
60 }
61}
62
Chris Lattnerea6cdd72007-08-31 22:09:40 +000063/// EmitCompoundStmt - Emit a compound statement {..} node. If GetLast is true,
64/// this captures the expression result of the last sub-statement and returns it
65/// (for use by the statement expression extension).
Chris Lattnere24c4cf2007-08-31 22:49:20 +000066RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast,
67 llvm::Value *AggLoc, bool isAggVol) {
Chris Lattner4b009652007-07-25 00:24:17 +000068 // FIXME: handle vla's etc.
Chris Lattnerea6cdd72007-08-31 22:09:40 +000069 if (S.body_empty() || !isa<Expr>(S.body_back())) GetLast = false;
Chris Lattner4b009652007-07-25 00:24:17 +000070
Chris Lattnerea6cdd72007-08-31 22:09:40 +000071 for (CompoundStmt::const_body_iterator I = S.body_begin(),
72 E = S.body_end()-GetLast; I != E; ++I)
Chris Lattner4b009652007-07-25 00:24:17 +000073 EmitStmt(*I);
Chris Lattnerea6cdd72007-08-31 22:09:40 +000074
75
76 if (!GetLast)
77 return RValue::get(0);
Chris Lattnere24c4cf2007-08-31 22:49:20 +000078
79 return EmitAnyExpr(cast<Expr>(S.body_back()), AggLoc);
Chris Lattner4b009652007-07-25 00:24:17 +000080}
81
82void CodeGenFunction::EmitBlock(llvm::BasicBlock *BB) {
83 // Emit a branch from this block to the next one if this was a real block. If
84 // this was just a fall-through block after a terminator, don't emit it.
85 llvm::BasicBlock *LastBB = Builder.GetInsertBlock();
86
87 if (LastBB->getTerminator()) {
88 // If the previous block is already terminated, don't touch it.
89 } else if (LastBB->empty() && LastBB->getValueName() == 0) {
90 // If the last block was an empty placeholder, remove it now.
91 // TODO: cache and reuse these.
92 Builder.GetInsertBlock()->eraseFromParent();
93 } else {
94 // Otherwise, create a fall-through branch.
95 Builder.CreateBr(BB);
96 }
97 CurFn->getBasicBlockList().push_back(BB);
98 Builder.SetInsertPoint(BB);
99}
100
101void CodeGenFunction::EmitLabelStmt(const LabelStmt &S) {
102 llvm::BasicBlock *NextBB = getBasicBlockForLabel(&S);
103
104 EmitBlock(NextBB);
105 EmitStmt(S.getSubStmt());
106}
107
108void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) {
109 Builder.CreateBr(getBasicBlockForLabel(S.getLabel()));
110
111 // Emit a block after the branch so that dead code after a goto has some place
112 // to go.
113 Builder.SetInsertPoint(new llvm::BasicBlock("", CurFn));
114}
115
116void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
117 // C99 6.8.4.1: The first substatement is executed if the expression compares
118 // unequal to 0. The condition must be a scalar type.
119 llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
120
121 llvm::BasicBlock *ContBlock = new llvm::BasicBlock("ifend");
122 llvm::BasicBlock *ThenBlock = new llvm::BasicBlock("ifthen");
123 llvm::BasicBlock *ElseBlock = ContBlock;
124
125 if (S.getElse())
126 ElseBlock = new llvm::BasicBlock("ifelse");
127
128 // Insert the conditional branch.
129 Builder.CreateCondBr(BoolCondVal, ThenBlock, ElseBlock);
130
131 // Emit the 'then' code.
132 EmitBlock(ThenBlock);
133 EmitStmt(S.getThen());
Devang Patel97299362007-09-28 21:49:18 +0000134 llvm::BasicBlock *BB = Builder.GetInsertBlock();
135 if (isDummyBlock(BB)) {
136 BB->eraseFromParent();
137 Builder.SetInsertPoint(ThenBlock);
138 }
139 else
140 Builder.CreateBr(ContBlock);
Chris Lattner4b009652007-07-25 00:24:17 +0000141
142 // Emit the 'else' code if present.
143 if (const Stmt *Else = S.getElse()) {
144 EmitBlock(ElseBlock);
145 EmitStmt(Else);
Devang Patel97299362007-09-28 21:49:18 +0000146 llvm::BasicBlock *BB = Builder.GetInsertBlock();
147 if (isDummyBlock(BB)) {
148 BB->eraseFromParent();
149 Builder.SetInsertPoint(ElseBlock);
150 }
151 else
152 Builder.CreateBr(ContBlock);
Chris Lattner4b009652007-07-25 00:24:17 +0000153 }
154
155 // Emit the continuation block for code after the if.
156 EmitBlock(ContBlock);
157}
158
159void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) {
160 // Emit the header for the loop, insert it, which will create an uncond br to
161 // it.
162 llvm::BasicBlock *LoopHeader = new llvm::BasicBlock("whilecond");
163 EmitBlock(LoopHeader);
164
165 // Evaluate the conditional in the while header. C99 6.8.5.1: The evaluation
166 // of the controlling expression takes place before each execution of the loop
167 // body.
168 llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
169
170 // TODO: while(1) is common, avoid extra exit blocks, etc. Be sure
171 // to correctly handle break/continue though.
172
173 // Create an exit block for when the condition fails, create a block for the
174 // body of the loop.
175 llvm::BasicBlock *ExitBlock = new llvm::BasicBlock("whileexit");
176 llvm::BasicBlock *LoopBody = new llvm::BasicBlock("whilebody");
177
178 // As long as the condition is true, go to the loop body.
179 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
180
181 // Store the blocks to use for break and continue.
182 BreakContinueStack.push_back(BreakContinue(ExitBlock, LoopHeader));
183
184 // Emit the loop body.
185 EmitBlock(LoopBody);
186 EmitStmt(S.getBody());
187
188 BreakContinueStack.pop_back();
189
190 // Cycle to the condition.
191 Builder.CreateBr(LoopHeader);
192
193 // Emit the exit block.
194 EmitBlock(ExitBlock);
195}
196
197void CodeGenFunction::EmitDoStmt(const DoStmt &S) {
198 // TODO: "do {} while (0)" is common in macros, avoid extra blocks. Be sure
199 // to correctly handle break/continue though.
200
201 // Emit the body for the loop, insert it, which will create an uncond br to
202 // it.
203 llvm::BasicBlock *LoopBody = new llvm::BasicBlock("dobody");
204 llvm::BasicBlock *AfterDo = new llvm::BasicBlock("afterdo");
205 EmitBlock(LoopBody);
206
207 llvm::BasicBlock *DoCond = new llvm::BasicBlock("docond");
208
209 // Store the blocks to use for break and continue.
210 BreakContinueStack.push_back(BreakContinue(AfterDo, DoCond));
211
212 // Emit the body of the loop into the block.
213 EmitStmt(S.getBody());
214
215 BreakContinueStack.pop_back();
216
217 EmitBlock(DoCond);
218
219 // C99 6.8.5.2: "The evaluation of the controlling expression takes place
220 // after each execution of the loop body."
221
222 // Evaluate the conditional in the while header.
223 // C99 6.8.5p2/p4: The first substatement is executed if the expression
224 // compares unequal to 0. The condition must be a scalar type.
225 llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
226
227 // As long as the condition is true, iterate the loop.
228 Builder.CreateCondBr(BoolCondVal, LoopBody, AfterDo);
229
230 // Emit the exit block.
231 EmitBlock(AfterDo);
232}
233
234void CodeGenFunction::EmitForStmt(const ForStmt &S) {
235 // FIXME: What do we do if the increment (f.e.) contains a stmt expression,
236 // which contains a continue/break?
237 // TODO: We could keep track of whether the loop body contains any
238 // break/continue statements and not create unnecessary blocks (like
239 // "afterfor" for a condless loop) if it doesn't.
240
241 // Evaluate the first part before the loop.
242 if (S.getInit())
243 EmitStmt(S.getInit());
244
245 // Start the loop with a block that tests the condition.
246 llvm::BasicBlock *CondBlock = new llvm::BasicBlock("forcond");
247 llvm::BasicBlock *AfterFor = new llvm::BasicBlock("afterfor");
248
249 EmitBlock(CondBlock);
250
251 // Evaluate the condition if present. If not, treat it as a non-zero-constant
252 // according to 6.8.5.3p2, aka, true.
253 if (S.getCond()) {
254 // C99 6.8.5p2/p4: The first substatement is executed if the expression
255 // compares unequal to 0. The condition must be a scalar type.
256 llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
257
258 // As long as the condition is true, iterate the loop.
259 llvm::BasicBlock *ForBody = new llvm::BasicBlock("forbody");
260 Builder.CreateCondBr(BoolCondVal, ForBody, AfterFor);
261 EmitBlock(ForBody);
262 } else {
263 // Treat it as a non-zero constant. Don't even create a new block for the
264 // body, just fall into it.
265 }
266
267 // If the for loop doesn't have an increment we can just use the
268 // condition as the continue block.
269 llvm::BasicBlock *ContinueBlock;
270 if (S.getInc())
271 ContinueBlock = new llvm::BasicBlock("forinc");
272 else
273 ContinueBlock = CondBlock;
274
275 // Store the blocks to use for break and continue.
276 BreakContinueStack.push_back(BreakContinue(AfterFor, ContinueBlock));
277
278 // If the condition is true, execute the body of the for stmt.
279 EmitStmt(S.getBody());
280
281 BreakContinueStack.pop_back();
282
283 if (S.getInc())
284 EmitBlock(ContinueBlock);
285
286 // If there is an increment, emit it next.
287 if (S.getInc())
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000288 EmitStmt(S.getInc());
Chris Lattner4b009652007-07-25 00:24:17 +0000289
290 // Finally, branch back up to the condition for the next iteration.
291 Builder.CreateBr(CondBlock);
292
293 // Emit the fall-through block.
294 EmitBlock(AfterFor);
295}
296
297/// EmitReturnStmt - Note that due to GCC extensions, this can have an operand
298/// if the function returns void, or may be missing one if the function returns
299/// non-void. Fun stuff :).
300void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {
Chris Lattner4b009652007-07-25 00:24:17 +0000301 // Emit the result value, even if unused, to evalute the side effects.
302 const Expr *RV = S.getRetValue();
Chris Lattner74b93032007-08-26 07:14:44 +0000303
Chris Lattner4b009652007-07-25 00:24:17 +0000304 QualType FnRetTy = CurFuncDecl->getType().getCanonicalType();
305 FnRetTy = cast<FunctionType>(FnRetTy)->getResultType();
306
307 if (FnRetTy->isVoidType()) {
Chris Lattner74b93032007-08-26 07:14:44 +0000308 // If the function returns void, emit ret void.
Chris Lattner4b009652007-07-25 00:24:17 +0000309 Builder.CreateRetVoid();
310 } else if (RV == 0) {
Chris Lattner74b93032007-08-26 07:14:44 +0000311 // Handle "return;" in a function that returns a value.
Chris Lattner4b009652007-07-25 00:24:17 +0000312 const llvm::Type *RetTy = CurFn->getFunctionType()->getReturnType();
313 if (RetTy == llvm::Type::VoidTy)
314 Builder.CreateRetVoid(); // struct return etc.
315 else
316 Builder.CreateRet(llvm::UndefValue::get(RetTy));
Chris Lattner74b93032007-08-26 07:14:44 +0000317 } else if (!hasAggregateLLVMType(RV->getType())) {
318 Builder.CreateRet(EmitScalarExpr(RV));
319 } else if (RV->getType()->isComplexType()) {
320 llvm::Value *SRetPtr = CurFn->arg_begin();
Chris Lattner8e1f6e02007-08-26 16:22:13 +0000321 EmitComplexExprIntoAddr(RV, SRetPtr, false);
Chris Lattner4b009652007-07-25 00:24:17 +0000322 } else {
Chris Lattner74b93032007-08-26 07:14:44 +0000323 llvm::Value *SRetPtr = CurFn->arg_begin();
324 EmitAggExpr(RV, SRetPtr, false);
Chris Lattner4b009652007-07-25 00:24:17 +0000325 }
326
327 // Emit a block after the branch so that dead code after a return has some
328 // place to go.
329 EmitBlock(new llvm::BasicBlock());
330}
331
332void CodeGenFunction::EmitDeclStmt(const DeclStmt &S) {
Steve Naroff2591e1b2007-09-13 23:52:58 +0000333 for (const ScopedDecl *Decl = S.getDecl(); Decl;
334 Decl = Decl->getNextDeclarator())
Chris Lattner4b009652007-07-25 00:24:17 +0000335 EmitDecl(*Decl);
336}
337
338void CodeGenFunction::EmitBreakStmt() {
339 assert(!BreakContinueStack.empty() && "break stmt not in a loop or switch!");
340
341 llvm::BasicBlock *Block = BreakContinueStack.back().BreakBlock;
342 Builder.CreateBr(Block);
343 EmitBlock(new llvm::BasicBlock());
344}
345
346void CodeGenFunction::EmitContinueStmt() {
347 assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
348
349 llvm::BasicBlock *Block = BreakContinueStack.back().ContinueBlock;
350 Builder.CreateBr(Block);
351 EmitBlock(new llvm::BasicBlock());
352}