blob: 88041b575e5a7a1b2925238fe5044025fb6ed9f5 [file] [log] [blame]
Chris Lattnere47e4402007-06-01 18:02:12 +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 llvm;
20using namespace clang;
21using namespace CodeGen;
22
23//===----------------------------------------------------------------------===//
24// Statement Emission
25//===----------------------------------------------------------------------===//
26
27void CodeGenFunction::EmitStmt(const Stmt *S) {
28 assert(S && "Null statement?");
29
30 switch (S->getStmtClass()) {
31 default:
32 // Must be an expression in a stmt context. Emit the value and ignore the
33 // result.
34 if (const Expr *E = dyn_cast<Expr>(S)) {
35 EmitExpr(E);
36 } else {
37 printf("Unimplemented stmt!\n");
38 S->dump();
39 }
40 break;
41 case Stmt::NullStmtClass: break;
42 case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break;
43 case Stmt::LabelStmtClass: EmitLabelStmt(cast<LabelStmt>(*S)); break;
44 case Stmt::GotoStmtClass: EmitGotoStmt(cast<GotoStmt>(*S)); break;
Chris Lattner946aa312007-06-05 03:59:43 +000045
Chris Lattnere47e4402007-06-01 18:02:12 +000046 case Stmt::IfStmtClass: EmitIfStmt(cast<IfStmt>(*S)); break;
Chris Lattner946aa312007-06-05 03:59:43 +000047 case Stmt::WhileStmtClass: EmitWhileStmt(cast<WhileStmt>(*S)); break;
48
Chris Lattner3f3dbee2007-06-02 03:19:07 +000049 case Stmt::ReturnStmtClass: EmitReturnStmt(cast<ReturnStmt>(*S)); break;
Chris Lattner84915fa2007-06-02 04:16:21 +000050 case Stmt::DeclStmtClass: EmitDeclStmt(cast<DeclStmt>(*S)); break;
Chris Lattnere47e4402007-06-01 18:02:12 +000051 }
52}
53
54void CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S) {
55 // FIXME: handle vla's etc.
56
57 for (CompoundStmt::const_body_iterator I = S.body_begin(), E = S.body_end();
58 I != E; ++I)
59 EmitStmt(*I);
60}
61
62void CodeGenFunction::EmitBlock(BasicBlock *BB) {
63 // Emit a branch from this block to the next one if this was a real block. If
64 // this was just a fall-through block after a terminator, don't emit it.
65 BasicBlock *LastBB = Builder.GetInsertBlock();
66
67 if (LastBB->getTerminator()) {
68 // If the previous block is already terminated, don't touch it.
69 } else if (LastBB->empty() && LastBB->getValueName() == 0) {
70 // If the last block was an empty placeholder, remove it now.
71 // TODO: cache and reuse these.
72 Builder.GetInsertBlock()->eraseFromParent();
73 } else {
74 // Otherwise, create a fall-through branch.
75 Builder.CreateBr(BB);
76 }
77 CurFn->getBasicBlockList().push_back(BB);
78 Builder.SetInsertPoint(BB);
79}
80
81void CodeGenFunction::EmitLabelStmt(const LabelStmt &S) {
82 llvm::BasicBlock *NextBB = getBasicBlockForLabel(&S);
83
84 EmitBlock(NextBB);
85 EmitStmt(S.getSubStmt());
86}
87
88void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) {
89 Builder.CreateBr(getBasicBlockForLabel(S.getLabel()));
90
91 // Emit a block after the branch so that dead code after a goto has some place
92 // to go.
93 Builder.SetInsertPoint(new BasicBlock("", CurFn));
94}
95
96void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
97 // Emit the if condition.
Chris Lattner946aa312007-06-05 03:59:43 +000098 QualType CondTy;
99 ExprResult CondVal = EmitExprWithUsualUnaryConversions(S.getCond(), CondTy);
Chris Lattnere47e4402007-06-01 18:02:12 +0000100
101 // C99 6.8.4.1: The first substatement is executed if the expression compares
102 // unequal to 0. The condition must be a scalar type.
Chris Lattner946aa312007-06-05 03:59:43 +0000103 llvm::Value *BoolCondVal = EvaluateScalarValueToBool(CondVal, CondTy);
Chris Lattnere47e4402007-06-01 18:02:12 +0000104
105 BasicBlock *ContBlock = new BasicBlock("ifend");
106 BasicBlock *ThenBlock = new BasicBlock("ifthen");
107 BasicBlock *ElseBlock = ContBlock;
108
109 if (S.getElse())
110 ElseBlock = new BasicBlock("ifelse");
111
112 // Insert the conditional branch.
113 Builder.CreateCondBr(BoolCondVal, ThenBlock, ElseBlock);
114
115 // Emit the 'then' code.
116 EmitBlock(ThenBlock);
117 EmitStmt(S.getThen());
118 Builder.CreateBr(ContBlock);
119
120 // Emit the 'else' code if present.
121 if (const Stmt *Else = S.getElse()) {
122 EmitBlock(ElseBlock);
123 EmitStmt(Else);
124 Builder.CreateBr(ContBlock);
125 }
126
127 // Emit the continuation block for code after the if.
128 EmitBlock(ContBlock);
129}
130
Chris Lattner946aa312007-06-05 03:59:43 +0000131void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) {
132 // FIXME: Handle continue/break.
133
134 // Emit the header for the loop, insert it, which will create an uncond br to
135 // it.
136 BasicBlock *LoopHeader = new BasicBlock("whilecond");
137 EmitBlock(LoopHeader);
138
139 // Evaluate the conditional in the while header. C99 6.8.5.1: The evaluation
140 // of the controlling expression takes place before each execution of the loop
141 // body.
142 QualType CondTy;
143 ExprResult CondVal = EmitExprWithUsualUnaryConversions(S.getCond(), CondTy);
144
145 // C99 6.8.5p2: The first substatement is executed if the expression compares
146 // unequal to 0. The condition must be a scalar type.
147 llvm::Value *BoolCondVal = EvaluateScalarValueToBool(CondVal, CondTy);
148
149 // TODO: while(1) is common, avoid extra exit blocks, etc.
150
151 // Create an exit block for when the condition fails, create a block for the
152 // body of the loop.
153 BasicBlock *ExitBlock = new BasicBlock("whileexit");
154 BasicBlock *LoopBody = new BasicBlock("whilebody");
155
156 // As long as the condition is true, go to the loop body.
157 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
158
159 // Emit the loop body.
160 EmitBlock(LoopBody);
161 EmitStmt(S.getBody());
162
163 // Cycle to the condition.
164 Builder.CreateBr(LoopHeader);
165
166 // Emit the exit block.
167 EmitBlock(ExitBlock);
168}
169
170
Chris Lattner3f3dbee2007-06-02 03:19:07 +0000171/// EmitReturnStmt - Note that due to GCC extensions, this can have an operand
172/// if the function returns void, or may be missing one if the function returns
173/// non-void. Fun stuff :).
174void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {
175 ExprResult RetVal;
176
177 // Emit the result value, even if unused, to evalute the side effects.
178 const Expr *RV = S.getRetValue();
179 if (RV)
180 RetVal = EmitExpr(RV);
181
182 if (CurFuncDecl->getType()->isVoidType()) {
183 // If the function returns void, emit ret void, and ignore the retval.
184 Builder.CreateRetVoid();
185 } else if (RV == 0) {
186 // "return;" in a function that returns a value.
187 const llvm::Type *RetTy = CurFn->getFunctionType()->getReturnType();
188 if (RetTy == llvm::Type::VoidTy)
189 Builder.CreateRetVoid(); // struct return etc.
190 else
191 Builder.CreateRet(llvm::UndefValue::get(RetTy));
192 } else if (RetVal.isScalar()) {
193 // FIXME: return should coerce its operand to the return type!
194 Builder.CreateRet(RetVal.getVal());
195 } else {
196 assert(0 && "FIXME: aggregate return unimp");
197 }
198
199 // Emit a block after the branch so that dead code after a goto has some place
200 // to go.
201 Builder.SetInsertPoint(new BasicBlock("", CurFn));
202}
203