blob: 84a9b5f28b0552bce68ae53e2cd23c1dac6edde2 [file] [log] [blame]
Chris Lattnere47e4402007-06-01 18:02:12 +00001//===--- CGExpr.cpp - Emit LLVM Code from Expressions ---------------------===//
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 Expr 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"
18using namespace llvm;
19using namespace clang;
20using namespace CodeGen;
21
Chris Lattnerd7f58862007-06-02 05:24:33 +000022//===--------------------------------------------------------------------===//
Chris Lattnerf0106d22007-06-02 19:33:17 +000023// Miscellaneous Helper Methods
24//===--------------------------------------------------------------------===//
25
26/// EvaluateScalarValueToBool - Evaluate the specified expression value to a
27/// boolean (i1) truth value. This is equivalent to "Val == 0".
28Value *CodeGenFunction::EvaluateScalarValueToBool(ExprResult Val, QualType Ty) {
29 Ty = Ty.getCanonicalType();
30 Value *Result;
31 if (const BuiltinType *BT = dyn_cast<BuiltinType>(Ty)) {
32 switch (BT->getKind()) {
33 default: assert(0 && "Unknown scalar value");
34 case BuiltinType::Bool:
35 Result = Val.getVal();
36 // Bool is already evaluated right.
37 assert(Result->getType() == llvm::Type::Int1Ty &&
38 "Unexpected bool value type!");
39 return Result;
40 case BuiltinType::Char:
41 case BuiltinType::SChar:
42 case BuiltinType::UChar:
43 case BuiltinType::Short:
44 case BuiltinType::UShort:
45 case BuiltinType::Int:
46 case BuiltinType::UInt:
47 case BuiltinType::Long:
48 case BuiltinType::ULong:
49 case BuiltinType::LongLong:
50 case BuiltinType::ULongLong:
51 // Code below handles simple integers.
52 break;
53 case BuiltinType::Float:
54 case BuiltinType::Double:
55 case BuiltinType::LongDouble: {
56 // Compare against 0.0 for fp scalars.
57 Result = Val.getVal();
58 llvm::Value *Zero = Constant::getNullValue(Result->getType());
59 // FIXME: llvm-gcc produces a une comparison: validate this is right.
60 Result = Builder.CreateFCmpUNE(Result, Zero, "tobool");
61 return Result;
62 }
63
64 case BuiltinType::FloatComplex:
65 case BuiltinType::DoubleComplex:
66 case BuiltinType::LongDoubleComplex:
67 assert(0 && "comparisons against complex not implemented yet");
68 }
69 } else {
70 assert((isa<PointerType>(Ty) ||
71 cast<TagType>(Ty)->getDecl()->getKind() == Decl::Enum) &&
72 "Unknown scalar type");
73 // Code below handles this fine.
74 }
75
76 // Usual case for integers, pointers, and enums: compare against zero.
77 Result = Val.getVal();
Chris Lattnera45c5af2007-06-02 19:47:04 +000078
79 // Because of the type rules of C, we often end up computing a logical value,
80 // then zero extending it to int, then wanting it as a logical value again.
81 // Optimize this common case.
82 if (llvm::ZExtInst *ZI = dyn_cast<ZExtInst>(Result)) {
83 if (ZI->getOperand(0)->getType() == llvm::Type::Int1Ty) {
84 Result = ZI->getOperand(0);
85 ZI->eraseFromParent();
86 return Result;
87 }
88 }
89
Chris Lattnerf0106d22007-06-02 19:33:17 +000090 llvm::Value *Zero = Constant::getNullValue(Result->getType());
91 return Builder.CreateICmpNE(Result, Zero, "tobool");
92}
93
Chris Lattnera45c5af2007-06-02 19:47:04 +000094//===----------------------------------------------------------------------===//
Chris Lattnerd7f58862007-06-02 05:24:33 +000095// LValue Expression Emission
Chris Lattnera45c5af2007-06-02 19:47:04 +000096//===----------------------------------------------------------------------===//
Chris Lattnerd7f58862007-06-02 05:24:33 +000097
98LValue CodeGenFunction::EmitLValue(const Expr *E) {
99 switch (E->getStmtClass()) {
100 default:
101 printf("Unimplemented lvalue expr!\n");
102 E->dump();
103 return LValue::getAddr(UndefValue::get(
104 llvm::PointerType::get(llvm::Type::Int32Ty)));
105
106 case Expr::DeclRefExprClass: return EmitDeclRefLValue(cast<DeclRefExpr>(E));
107 }
108}
109
110
111LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
112 const Decl *D = E->getDecl();
113 if (isa<BlockVarDecl>(D)) {
114 Value *V = LocalDeclMap[D];
115 assert(V && "BlockVarDecl not entered in LocalDeclMap?");
116 return LValue::getAddr(V);
117 }
118 assert(0 && "Unimp declref");
119}
Chris Lattnere47e4402007-06-01 18:02:12 +0000120
121//===--------------------------------------------------------------------===//
122// Expression Emission
123//===--------------------------------------------------------------------===//
124
125ExprResult CodeGenFunction::EmitExpr(const Expr *E) {
126 assert(E && "Null expression?");
127
128 switch (E->getStmtClass()) {
129 default:
130 printf("Unimplemented expr!\n");
131 E->dump();
132 return ExprResult::get(UndefValue::get(llvm::Type::Int32Ty));
Chris Lattnerd7f58862007-06-02 05:24:33 +0000133
134 // l-values.
135 case Expr::DeclRefExprClass: {
136 // FIXME: EnumConstantDecl's are not lvalues.
137 LValue LV = EmitLValue(E);
138 // FIXME: this is silly.
139 assert(!LV.isBitfield());
140 return ExprResult::get(Builder.CreateLoad(LV.getAddress(), "tmp"));
141 }
142
143 // Leaf expressions.
144 case Expr::IntegerLiteralClass:
Chris Lattnere47e4402007-06-01 18:02:12 +0000145 return EmitIntegerLiteral(cast<IntegerLiteral>(E));
Chris Lattnerdb91b162007-06-02 00:16:28 +0000146
Chris Lattnerd7f58862007-06-02 05:24:33 +0000147 // Operators.
148 case Expr::ParenExprClass:
149 return EmitExpr(cast<ParenExpr>(E)->getSubExpr());
Chris Lattnerf0106d22007-06-02 19:33:17 +0000150 case Expr::UnaryOperatorClass:
151 return EmitUnaryOperator(cast<UnaryOperator>(E));
Chris Lattnerd7f58862007-06-02 05:24:33 +0000152 case Expr::BinaryOperatorClass:
Chris Lattnerdb91b162007-06-02 00:16:28 +0000153 return EmitBinaryOperator(cast<BinaryOperator>(E));
Chris Lattnere47e4402007-06-01 18:02:12 +0000154 }
155
156}
157
158ExprResult CodeGenFunction::EmitIntegerLiteral(const IntegerLiteral *E) {
159 return ExprResult::get(ConstantInt::get(E->getValue()));
160}
161
Chris Lattnerf0106d22007-06-02 19:33:17 +0000162//===--------------------------------------------------------------------===//
163// Unary Operator Emission
164//===--------------------------------------------------------------------===//
165
166ExprResult CodeGenFunction::EmitUnaryOperator(const UnaryOperator *E) {
167 switch (E->getOpcode()) {
168 default:
169 printf("Unimplemented unary expr!\n");
170 E->dump();
171 return ExprResult::get(UndefValue::get(llvm::Type::Int32Ty));
172 case UnaryOperator::LNot: return EmitUnaryLNot(E);
173 }
174}
175
176/// C99 6.5.3.3
177ExprResult CodeGenFunction::EmitUnaryLNot(const UnaryOperator *E) {
178 ExprResult Op = EmitExpr(E->getSubExpr());
179
180 //UsualUnary();
181
182 // Compare to zero.
183 Value *BoolVal = EvaluateScalarValueToBool(Op, E->getSubExpr()->getType());
184
185 // Invert value.
Chris Lattnera45c5af2007-06-02 19:47:04 +0000186 // TODO: Could dynamically modify easy computations here. For example, if
187 // the operand is an icmp ne, turn into icmp eq.
Chris Lattnerf0106d22007-06-02 19:33:17 +0000188 BoolVal = Builder.CreateNot(BoolVal, "lnot");
189
190 // ZExt result to int.
191 const llvm::Type *ResTy = ConvertType(E->getType(), E->getOperatorLoc());
192 return ExprResult::get(Builder.CreateZExt(BoolVal, ResTy, "lnot.ext"));
193}
194
Chris Lattnere47e4402007-06-01 18:02:12 +0000195
Chris Lattnerdb91b162007-06-02 00:16:28 +0000196//===--------------------------------------------------------------------===//
197// Binary Operator Emission
198//===--------------------------------------------------------------------===//
199
200// FIXME describe.
201void CodeGenFunction::EmitUsualArithmeticConversions(const BinaryOperator *E,
202 ExprResult &LHS,
203 ExprResult &RHS) {
204 // FIXME: implement right.
205 LHS = EmitExpr(E->getLHS());
206 RHS = EmitExpr(E->getRHS());
207}
208
209
210ExprResult CodeGenFunction::EmitBinaryOperator(const BinaryOperator *E) {
211 switch (E->getOpcode()) {
212 default:
213 printf("Unimplemented expr!\n");
214 E->dump();
215 return ExprResult::get(UndefValue::get(llvm::Type::Int32Ty));
216 case BinaryOperator::Add: return EmitBinaryAdd(E);
217 }
218}
219
220
221ExprResult CodeGenFunction::EmitBinaryAdd(const BinaryOperator *E) {
222 ExprResult LHS, RHS;
223
224 EmitUsualArithmeticConversions(E, LHS, RHS);
225
226
227 return ExprResult::get(Builder.CreateAdd(LHS.getVal(), RHS.getVal(), "tmp"));
228}