implement codegen of while stmts and lvalue evaluation of paren exprs :)

llvm-svn: 39582
This commit is contained in:
Chris Lattner 2007-06-05 03:59:43 +00:00
parent 71b59a9a29
commit 946aa31f02
5 changed files with 52 additions and 28 deletions

View File

@ -105,6 +105,7 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
llvm::PointerType::get(llvm::Type::Int32Ty)));
case Expr::DeclRefExprClass: return EmitDeclRefLValue(cast<DeclRefExpr>(E));
case Expr::ParenExprClass:return EmitLValue(cast<ParenExpr>(E)->getSubExpr());
}
}
@ -364,6 +365,6 @@ ExprResult CodeGenFunction::EmitBinaryAdd(const BinaryOperator *E) {
EmitUsualArithmeticConversions(E, LHS, RHS);
// FIXME: This doesn't handle complex addition yet.
return ExprResult::get(Builder.CreateAdd(LHS.getVal(), RHS.getVal(), "tmp"));
}

View File

@ -42,7 +42,10 @@ void CodeGenFunction::EmitStmt(const Stmt *S) {
case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break;
case Stmt::LabelStmtClass: EmitLabelStmt(cast<LabelStmt>(*S)); break;
case Stmt::GotoStmtClass: EmitGotoStmt(cast<GotoStmt>(*S)); break;
case Stmt::IfStmtClass: EmitIfStmt(cast<IfStmt>(*S)); break;
case Stmt::WhileStmtClass: EmitWhileStmt(cast<WhileStmt>(*S)); break;
case Stmt::ReturnStmtClass: EmitReturnStmt(cast<ReturnStmt>(*S)); break;
case Stmt::DeclStmtClass: EmitDeclStmt(cast<DeclStmt>(*S)); break;
}
@ -92,13 +95,12 @@ void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) {
void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
// Emit the if condition.
ExprResult CondVal = EmitExpr(S.getCond());
QualType CondTy = S.getCond()->getType().getCanonicalType();
QualType CondTy;
ExprResult CondVal = EmitExprWithUsualUnaryConversions(S.getCond(), CondTy);
// C99 6.8.4.1: The first substatement is executed if the expression compares
// unequal to 0. The condition must be a scalar type.
llvm::Value *BoolCondVal =
EvaluateScalarValueToBool(CondVal, S.getCond()->getType());
llvm::Value *BoolCondVal = EvaluateScalarValueToBool(CondVal, CondTy);
BasicBlock *ContBlock = new BasicBlock("ifend");
BasicBlock *ThenBlock = new BasicBlock("ifthen");
@ -126,6 +128,46 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
EmitBlock(ContBlock);
}
void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) {
// FIXME: Handle continue/break.
// Emit the header for the loop, insert it, which will create an uncond br to
// it.
BasicBlock *LoopHeader = new BasicBlock("whilecond");
EmitBlock(LoopHeader);
// Evaluate the conditional in the while header. C99 6.8.5.1: The evaluation
// of the controlling expression takes place before each execution of the loop
// body.
QualType CondTy;
ExprResult CondVal = EmitExprWithUsualUnaryConversions(S.getCond(), CondTy);
// C99 6.8.5p2: The first substatement is executed if the expression compares
// unequal to 0. The condition must be a scalar type.
llvm::Value *BoolCondVal = EvaluateScalarValueToBool(CondVal, CondTy);
// TODO: while(1) is common, avoid extra exit blocks, etc.
// Create an exit block for when the condition fails, create a block for the
// body of the loop.
BasicBlock *ExitBlock = new BasicBlock("whileexit");
BasicBlock *LoopBody = new BasicBlock("whilebody");
// As long as the condition is true, go to the loop body.
Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
// Emit the loop body.
EmitBlock(LoopBody);
EmitStmt(S.getBody());
// Cycle to the condition.
Builder.CreateBr(LoopHeader);
// Emit the exit block.
EmitBlock(ExitBlock);
}
/// EmitReturnStmt - Note that due to GCC extensions, this can have an operand
/// if the function returns void, or may be missing one if the function returns
/// non-void. Fun stuff :).

View File

@ -32,6 +32,7 @@ namespace clang {
class LabelStmt;
class GotoStmt;
class IfStmt;
class WhileStmt;
class ReturnStmt;
class DeclStmt;
@ -168,6 +169,7 @@ public:
void EmitLabelStmt(const LabelStmt &S);
void EmitGotoStmt(const GotoStmt &S);
void EmitIfStmt(const IfStmt &S);
void EmitWhileStmt(const WhileStmt &S);
void EmitReturnStmt(const ReturnStmt &S);
//===--------------------------------------------------------------------===//

View File

@ -106,23 +106,6 @@
DED7D9E50A5257F6003AD0FB /* ScratchBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D9E40A5257F6003AD0FB /* ScratchBuffer.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXBuildStyle section */
8424C78B0C133C77008BC1FE /* Development */ = {
isa = PBXBuildStyle;
buildSettings = {
COPY_PHASE_STRIP = NO;
};
name = Development;
};
8424C78C0C133C77008BC1FE /* Deployment */ = {
isa = PBXBuildStyle;
buildSettings = {
COPY_PHASE_STRIP = YES;
};
name = Deployment;
};
/* End PBXBuildStyle section */
/* Begin PBXCopyFilesBuildPhase section */
8DD76F690486A84900D96B5E /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
@ -564,12 +547,6 @@
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
buildSettings = {
};
buildStyles = (
8424C78B0C133C77008BC1FE /* Development */,
8424C78C0C133C77008BC1FE /* Deployment */,
);
hasScannedForEncodings = 1;
mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
projectDirPath = "";

View File

@ -236,7 +236,9 @@ public:
: Stmt(WhileStmtClass), Cond(cond), Body(body) {}
Expr *getCond() { return Cond; }
const Expr *getCond() const { return Cond; }
Stmt *getBody() { return Body; }
const Stmt *getBody() const { return Body; }
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {