From 946aa31f026f29f41394c3e8776fcaf8f67d984c Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 5 Jun 2007 03:59:43 +0000 Subject: [PATCH] implement codegen of while stmts and lvalue evaluation of paren exprs :) llvm-svn: 39582 --- clang/CodeGen/CGExpr.cpp | 3 +- clang/CodeGen/CGStmt.cpp | 50 ++++++++++++++++++++++++--- clang/CodeGen/CodeGenFunction.h | 2 ++ clang/clang.xcodeproj/project.pbxproj | 23 ------------ clang/include/clang/AST/Stmt.h | 2 ++ 5 files changed, 52 insertions(+), 28 deletions(-) diff --git a/clang/CodeGen/CGExpr.cpp b/clang/CodeGen/CGExpr.cpp index 17c7c016743b..1e77185cd0b2 100644 --- a/clang/CodeGen/CGExpr.cpp +++ b/clang/CodeGen/CGExpr.cpp @@ -105,6 +105,7 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) { llvm::PointerType::get(llvm::Type::Int32Ty))); case Expr::DeclRefExprClass: return EmitDeclRefLValue(cast(E)); + case Expr::ParenExprClass:return EmitLValue(cast(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")); } \ No newline at end of file diff --git a/clang/CodeGen/CGStmt.cpp b/clang/CodeGen/CGStmt.cpp index 6332f3ecd5fe..88041b575e5a 100644 --- a/clang/CodeGen/CGStmt.cpp +++ b/clang/CodeGen/CGStmt.cpp @@ -42,7 +42,10 @@ void CodeGenFunction::EmitStmt(const Stmt *S) { case Stmt::CompoundStmtClass: EmitCompoundStmt(cast(*S)); break; case Stmt::LabelStmtClass: EmitLabelStmt(cast(*S)); break; case Stmt::GotoStmtClass: EmitGotoStmt(cast(*S)); break; + case Stmt::IfStmtClass: EmitIfStmt(cast(*S)); break; + case Stmt::WhileStmtClass: EmitWhileStmt(cast(*S)); break; + case Stmt::ReturnStmtClass: EmitReturnStmt(cast(*S)); break; case Stmt::DeclStmtClass: EmitDeclStmt(cast(*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 :). diff --git a/clang/CodeGen/CodeGenFunction.h b/clang/CodeGen/CodeGenFunction.h index 0a2685c853ac..4df50af90ac1 100644 --- a/clang/CodeGen/CodeGenFunction.h +++ b/clang/CodeGen/CodeGenFunction.h @@ -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); //===--------------------------------------------------------------------===// diff --git a/clang/clang.xcodeproj/project.pbxproj b/clang/clang.xcodeproj/project.pbxproj index 9f89fa307941..f7e7fbaf44c2 100644 --- a/clang/clang.xcodeproj/project.pbxproj +++ b/clang/clang.xcodeproj/project.pbxproj @@ -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 = ""; diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index c1d3b2025397..3f46cf717dbf 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -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) {