blob: fb2f7841f283cca40dcc164af3da0ed239ebbdca [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//
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:
31 // Must be an expression in a stmt context. Emit the value and ignore the
32 // result.
33 if (const Expr *E = dyn_cast<Expr>(S)) {
34 EmitExpr(E);
35 } else {
36 printf("Unimplemented stmt!\n");
37 S->dump();
38 }
39 break;
40 case Stmt::NullStmtClass: break;
41 case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break;
42 case Stmt::LabelStmtClass: EmitLabelStmt(cast<LabelStmt>(*S)); break;
43 case Stmt::GotoStmtClass: EmitGotoStmt(cast<GotoStmt>(*S)); break;
44
45 case Stmt::IfStmtClass: EmitIfStmt(cast<IfStmt>(*S)); break;
46 case Stmt::WhileStmtClass: EmitWhileStmt(cast<WhileStmt>(*S)); break;
47 case Stmt::DoStmtClass: EmitDoStmt(cast<DoStmt>(*S)); break;
48 case Stmt::ForStmtClass: EmitForStmt(cast<ForStmt>(*S)); break;
49
50 case Stmt::ReturnStmtClass: EmitReturnStmt(cast<ReturnStmt>(*S)); break;
51 case Stmt::DeclStmtClass: EmitDeclStmt(cast<DeclStmt>(*S)); break;
52 }
53}
54
55void CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S) {
56 // FIXME: handle vla's etc.
57
58 for (CompoundStmt::const_body_iterator I = S.body_begin(), E = S.body_end();
59 I != E; ++I)
60 EmitStmt(*I);
61}
62
63void CodeGenFunction::EmitBlock(llvm::BasicBlock *BB) {
64 // Emit a branch from this block to the next one if this was a real block. If
65 // this was just a fall-through block after a terminator, don't emit it.
66 llvm::BasicBlock *LastBB = Builder.GetInsertBlock();
67
68 if (LastBB->getTerminator()) {
69 // If the previous block is already terminated, don't touch it.
70 } else if (LastBB->empty() && LastBB->getValueName() == 0) {
71 // If the last block was an empty placeholder, remove it now.
72 // TODO: cache and reuse these.
73 Builder.GetInsertBlock()->eraseFromParent();
74 } else {
75 // Otherwise, create a fall-through branch.
76 Builder.CreateBr(BB);
77 }
78 CurFn->getBasicBlockList().push_back(BB);
79 Builder.SetInsertPoint(BB);
80}
81
82void CodeGenFunction::EmitLabelStmt(const LabelStmt &S) {
83 llvm::BasicBlock *NextBB = getBasicBlockForLabel(&S);
84
85 EmitBlock(NextBB);
86 EmitStmt(S.getSubStmt());
87}
88
89void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) {
90 Builder.CreateBr(getBasicBlockForLabel(S.getLabel()));
91
92 // Emit a block after the branch so that dead code after a goto has some place
93 // to go.
94 Builder.SetInsertPoint(new llvm::BasicBlock("", CurFn));
95}
96
97void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
98 // C99 6.8.4.1: The first substatement is executed if the expression compares
99 // unequal to 0. The condition must be a scalar type.
100 llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
101
102 llvm::BasicBlock *ContBlock = new llvm::BasicBlock("ifend");
103 llvm::BasicBlock *ThenBlock = new llvm::BasicBlock("ifthen");
104 llvm::BasicBlock *ElseBlock = ContBlock;
105
106 if (S.getElse())
107 ElseBlock = new llvm::BasicBlock("ifelse");
108
109 // Insert the conditional branch.
110 Builder.CreateCondBr(BoolCondVal, ThenBlock, ElseBlock);
111
112 // Emit the 'then' code.
113 EmitBlock(ThenBlock);
114 EmitStmt(S.getThen());
115 Builder.CreateBr(ContBlock);
116
117 // Emit the 'else' code if present.
118 if (const Stmt *Else = S.getElse()) {
119 EmitBlock(ElseBlock);
120 EmitStmt(Else);
121 Builder.CreateBr(ContBlock);
122 }
123
124 // Emit the continuation block for code after the if.
125 EmitBlock(ContBlock);
126}
127
128void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) {
129 // FIXME: Handle continue/break.
130
131 // Emit the header for the loop, insert it, which will create an uncond br to
132 // it.
133 llvm::BasicBlock *LoopHeader = new llvm::BasicBlock("whilecond");
134 EmitBlock(LoopHeader);
135
136 // Evaluate the conditional in the while header. C99 6.8.5.1: The evaluation
137 // of the controlling expression takes place before each execution of the loop
138 // body.
139 llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
140
141 // TODO: while(1) is common, avoid extra exit blocks, etc. Be sure
142 // to correctly handle break/continue though.
143
144 // Create an exit block for when the condition fails, create a block for the
145 // body of the loop.
146 llvm::BasicBlock *ExitBlock = new llvm::BasicBlock("whileexit");
147 llvm::BasicBlock *LoopBody = new llvm::BasicBlock("whilebody");
148
149 // As long as the condition is true, go to the loop body.
150 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
151
152 // Emit the loop body.
153 EmitBlock(LoopBody);
154 EmitStmt(S.getBody());
155
156 // Cycle to the condition.
157 Builder.CreateBr(LoopHeader);
158
159 // Emit the exit block.
160 EmitBlock(ExitBlock);
161}
162
163void CodeGenFunction::EmitDoStmt(const DoStmt &S) {
164 // FIXME: Handle continue/break.
165 // TODO: "do {} while (0)" is common in macros, avoid extra blocks. Be sure
166 // to correctly handle break/continue though.
167
168 // Emit the body for the loop, insert it, which will create an uncond br to
169 // it.
170 llvm::BasicBlock *LoopBody = new llvm::BasicBlock("dobody");
171 llvm::BasicBlock *AfterDo = new llvm::BasicBlock("afterdo");
172 EmitBlock(LoopBody);
173
174 // Emit the body of the loop into the block.
175 EmitStmt(S.getBody());
176
177 // C99 6.8.5.2: "The evaluation of the controlling expression takes place
178 // after each execution of the loop body."
179
180 // Evaluate the conditional in the while header.
181 // C99 6.8.5p2/p4: The first substatement is executed if the expression
182 // compares unequal to 0. The condition must be a scalar type.
183 llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
184
185 // As long as the condition is true, iterate the loop.
186 Builder.CreateCondBr(BoolCondVal, LoopBody, AfterDo);
187
188 // Emit the exit block.
189 EmitBlock(AfterDo);
190}
191
192void CodeGenFunction::EmitForStmt(const ForStmt &S) {
193 // FIXME: Handle continue/break.
194 // FIXME: What do we do if the increment (f.e.) contains a stmt expression,
195 // which contains a continue/break?
196
197 // Evaluate the first part before the loop.
198 if (S.getInit())
199 EmitStmt(S.getInit());
200
201 // Start the loop with a block that tests the condition.
202 llvm::BasicBlock *CondBlock = new llvm::BasicBlock("forcond");
203 llvm::BasicBlock *AfterFor = 0;
204 EmitBlock(CondBlock);
205
206 // Evaluate the condition if present. If not, treat it as a non-zero-constant
207 // according to 6.8.5.3p2, aka, true.
208 if (S.getCond()) {
209 // C99 6.8.5p2/p4: The first substatement is executed if the expression
210 // compares unequal to 0. The condition must be a scalar type.
211 llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
212
213 // As long as the condition is true, iterate the loop.
214 llvm::BasicBlock *ForBody = new llvm::BasicBlock("forbody");
215 AfterFor = new llvm::BasicBlock("afterfor");
216 Builder.CreateCondBr(BoolCondVal, ForBody, AfterFor);
217 EmitBlock(ForBody);
218 } else {
219 // Treat it as a non-zero constant. Don't even create a new block for the
220 // body, just fall into it.
221 }
222
223 // If the condition is true, execute the body of the for stmt.
224 EmitStmt(S.getBody());
225
226 // If there is an increment, emit it next.
227 if (S.getInc())
228 EmitExpr(S.getInc());
229
230 // Finally, branch back up to the condition for the next iteration.
231 Builder.CreateBr(CondBlock);
232
233 // Emit the fall-through block if there is any.
234 if (AfterFor)
235 EmitBlock(AfterFor);
236 else
237 EmitBlock(new llvm::BasicBlock());
238}
239
240/// EmitReturnStmt - Note that due to GCC extensions, this can have an operand
241/// if the function returns void, or may be missing one if the function returns
242/// non-void. Fun stuff :).
243void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {
244 RValue RetVal;
245
246 // Emit the result value, even if unused, to evalute the side effects.
247 const Expr *RV = S.getRetValue();
248 if (RV)
249 RetVal = EmitExpr(RV);
250
251 QualType FnRetTy = CurFuncDecl->getType().getCanonicalType();
252 FnRetTy = cast<FunctionType>(FnRetTy)->getResultType();
253
254 if (FnRetTy->isVoidType()) {
255 // If the function returns void, emit ret void, and ignore the retval.
256 Builder.CreateRetVoid();
257 } else if (RV == 0) {
258 // "return;" in a function that returns a value.
259 const llvm::Type *RetTy = CurFn->getFunctionType()->getReturnType();
260 if (RetTy == llvm::Type::VoidTy)
261 Builder.CreateRetVoid(); // struct return etc.
262 else
263 Builder.CreateRet(llvm::UndefValue::get(RetTy));
264 } else {
265 // Do implicit conversions to the returned type.
266 RetVal = EmitConversion(RetVal, RV->getType(), FnRetTy);
267
268 if (RetVal.isScalar()) {
269 Builder.CreateRet(RetVal.getVal());
270 } else {
271 llvm::Value *SRetPtr = CurFn->arg_begin();
272 EmitStoreThroughLValue(RetVal, LValue::MakeAddr(SRetPtr), FnRetTy);
273 }
274 }
275
276 // Emit a block after the branch so that dead code after a return has some
277 // place to go.
278 EmitBlock(new llvm::BasicBlock());
279}
280
281void CodeGenFunction::EmitDeclStmt(const DeclStmt &S) {
282 for (const Decl *Decl = S.getDecl(); Decl; Decl = Decl->getNextDeclarator())
283 EmitDecl(*Decl);
284}