2007-06-01 18:02:12 +00:00
|
|
|
//===--- CGExpr.cpp - Emit LLVM Code from Expressions ---------------------===//
|
|
|
|
|
//
|
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
|
//
|
|
|
|
|
// This file was developed by Chris Lattner and is distributed under
|
|
|
|
|
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
|
|
|
|
//
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
//
|
|
|
|
|
// This contains code to emit Expr nodes as LLVM code.
|
|
|
|
|
//
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
|
|
#include "CodeGenFunction.h"
|
|
|
|
|
#include "clang/AST/AST.h"
|
|
|
|
|
#include "llvm/Constants.h"
|
|
|
|
|
#include "llvm/DerivedTypes.h"
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
using namespace clang;
|
|
|
|
|
using namespace CodeGen;
|
|
|
|
|
|
2007-06-02 19:33:17 +00:00
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
|
// Miscellaneous Helper Methods
|
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
|
|
/// EvaluateScalarValueToBool - Evaluate the specified expression value to a
|
|
|
|
|
/// boolean (i1) truth value. This is equivalent to "Val == 0".
|
|
|
|
|
Value *CodeGenFunction::EvaluateScalarValueToBool(ExprResult Val, QualType Ty) {
|
|
|
|
|
Ty = Ty.getCanonicalType();
|
|
|
|
|
Value *Result;
|
|
|
|
|
if (const BuiltinType *BT = dyn_cast<BuiltinType>(Ty)) {
|
|
|
|
|
switch (BT->getKind()) {
|
|
|
|
|
default: assert(0 && "Unknown scalar value");
|
|
|
|
|
case BuiltinType::Bool:
|
|
|
|
|
Result = Val.getVal();
|
|
|
|
|
// Bool is already evaluated right.
|
|
|
|
|
assert(Result->getType() == llvm::Type::Int1Ty &&
|
|
|
|
|
"Unexpected bool value type!");
|
|
|
|
|
return Result;
|
|
|
|
|
case BuiltinType::Char:
|
|
|
|
|
case BuiltinType::SChar:
|
|
|
|
|
case BuiltinType::UChar:
|
|
|
|
|
case BuiltinType::Short:
|
|
|
|
|
case BuiltinType::UShort:
|
|
|
|
|
case BuiltinType::Int:
|
|
|
|
|
case BuiltinType::UInt:
|
|
|
|
|
case BuiltinType::Long:
|
|
|
|
|
case BuiltinType::ULong:
|
|
|
|
|
case BuiltinType::LongLong:
|
|
|
|
|
case BuiltinType::ULongLong:
|
|
|
|
|
// Code below handles simple integers.
|
|
|
|
|
break;
|
|
|
|
|
case BuiltinType::Float:
|
|
|
|
|
case BuiltinType::Double:
|
|
|
|
|
case BuiltinType::LongDouble: {
|
|
|
|
|
// Compare against 0.0 for fp scalars.
|
|
|
|
|
Result = Val.getVal();
|
|
|
|
|
llvm::Value *Zero = Constant::getNullValue(Result->getType());
|
|
|
|
|
// FIXME: llvm-gcc produces a une comparison: validate this is right.
|
|
|
|
|
Result = Builder.CreateFCmpUNE(Result, Zero, "tobool");
|
|
|
|
|
return Result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case BuiltinType::FloatComplex:
|
|
|
|
|
case BuiltinType::DoubleComplex:
|
|
|
|
|
case BuiltinType::LongDoubleComplex:
|
|
|
|
|
assert(0 && "comparisons against complex not implemented yet");
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
assert((isa<PointerType>(Ty) ||
|
|
|
|
|
cast<TagType>(Ty)->getDecl()->getKind() == Decl::Enum) &&
|
|
|
|
|
"Unknown scalar type");
|
|
|
|
|
// Code below handles this fine.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Usual case for integers, pointers, and enums: compare against zero.
|
|
|
|
|
Result = Val.getVal();
|
2007-06-02 19:47:04 +00:00
|
|
|
|
|
|
|
|
// Because of the type rules of C, we often end up computing a logical value,
|
|
|
|
|
// then zero extending it to int, then wanting it as a logical value again.
|
|
|
|
|
// Optimize this common case.
|
|
|
|
|
if (llvm::ZExtInst *ZI = dyn_cast<ZExtInst>(Result)) {
|
|
|
|
|
if (ZI->getOperand(0)->getType() == llvm::Type::Int1Ty) {
|
|
|
|
|
Result = ZI->getOperand(0);
|
|
|
|
|
ZI->eraseFromParent();
|
|
|
|
|
return Result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-06-02 19:33:17 +00:00
|
|
|
llvm::Value *Zero = Constant::getNullValue(Result->getType());
|
|
|
|
|
return Builder.CreateICmpNE(Result, Zero, "tobool");
|
|
|
|
|
}
|
|
|
|
|
|
2007-06-02 19:47:04 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
2007-06-02 05:24:33 +00:00
|
|
|
// LValue Expression Emission
|
2007-06-02 19:47:04 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
2007-06-02 05:24:33 +00:00
|
|
|
|
|
|
|
|
LValue CodeGenFunction::EmitLValue(const Expr *E) {
|
|
|
|
|
switch (E->getStmtClass()) {
|
|
|
|
|
default:
|
|
|
|
|
printf("Unimplemented lvalue expr!\n");
|
|
|
|
|
E->dump();
|
|
|
|
|
return LValue::getAddr(UndefValue::get(
|
|
|
|
|
llvm::PointerType::get(llvm::Type::Int32Ty)));
|
|
|
|
|
|
|
|
|
|
case Expr::DeclRefExprClass: return EmitDeclRefLValue(cast<DeclRefExpr>(E));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
|
|
|
|
|
const Decl *D = E->getDecl();
|
|
|
|
|
if (isa<BlockVarDecl>(D)) {
|
|
|
|
|
Value *V = LocalDeclMap[D];
|
|
|
|
|
assert(V && "BlockVarDecl not entered in LocalDeclMap?");
|
|
|
|
|
return LValue::getAddr(V);
|
|
|
|
|
}
|
|
|
|
|
assert(0 && "Unimp declref");
|
|
|
|
|
}
|
2007-06-01 18:02:12 +00:00
|
|
|
|
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
|
// Expression Emission
|
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
|
|
ExprResult CodeGenFunction::EmitExpr(const Expr *E) {
|
|
|
|
|
assert(E && "Null expression?");
|
|
|
|
|
|
|
|
|
|
switch (E->getStmtClass()) {
|
|
|
|
|
default:
|
|
|
|
|
printf("Unimplemented expr!\n");
|
|
|
|
|
E->dump();
|
|
|
|
|
return ExprResult::get(UndefValue::get(llvm::Type::Int32Ty));
|
2007-06-02 05:24:33 +00:00
|
|
|
|
|
|
|
|
// l-values.
|
|
|
|
|
case Expr::DeclRefExprClass: {
|
|
|
|
|
// FIXME: EnumConstantDecl's are not lvalues.
|
|
|
|
|
LValue LV = EmitLValue(E);
|
|
|
|
|
// FIXME: this is silly.
|
|
|
|
|
assert(!LV.isBitfield());
|
|
|
|
|
return ExprResult::get(Builder.CreateLoad(LV.getAddress(), "tmp"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Leaf expressions.
|
|
|
|
|
case Expr::IntegerLiteralClass:
|
2007-06-01 18:02:12 +00:00
|
|
|
return EmitIntegerLiteral(cast<IntegerLiteral>(E));
|
2007-06-02 00:16:28 +00:00
|
|
|
|
2007-06-02 05:24:33 +00:00
|
|
|
// Operators.
|
|
|
|
|
case Expr::ParenExprClass:
|
|
|
|
|
return EmitExpr(cast<ParenExpr>(E)->getSubExpr());
|
2007-06-02 19:33:17 +00:00
|
|
|
case Expr::UnaryOperatorClass:
|
|
|
|
|
return EmitUnaryOperator(cast<UnaryOperator>(E));
|
2007-06-02 05:24:33 +00:00
|
|
|
case Expr::BinaryOperatorClass:
|
2007-06-02 00:16:28 +00:00
|
|
|
return EmitBinaryOperator(cast<BinaryOperator>(E));
|
2007-06-01 18:02:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ExprResult CodeGenFunction::EmitIntegerLiteral(const IntegerLiteral *E) {
|
|
|
|
|
return ExprResult::get(ConstantInt::get(E->getValue()));
|
|
|
|
|
}
|
|
|
|
|
|
2007-06-02 19:33:17 +00:00
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
|
// Unary Operator Emission
|
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
|
|
2007-06-02 22:49:07 +00:00
|
|
|
ExprResult CodeGenFunction::EmitExprWithUsualUnaryConversions(const Expr *E,
|
|
|
|
|
QualType &ResTy) {
|
|
|
|
|
ResTy = E->getType().getCanonicalType();
|
|
|
|
|
|
|
|
|
|
if (isa<FunctionType>(ResTy)) { // C99 6.3.2.1p4
|
|
|
|
|
// Functions are promoted to their address.
|
|
|
|
|
ResTy = getContext().getPointerType(ResTy);
|
|
|
|
|
return ExprResult::get(EmitLValue(E).getAddress());
|
|
|
|
|
} else if (const ArrayType *ary = dyn_cast<ArrayType>(ResTy)) {
|
|
|
|
|
// C99 6.3.2.1p3
|
|
|
|
|
ResTy = getContext().getPointerType(ary->getElementType());
|
|
|
|
|
|
|
|
|
|
// FIXME: For now we assume that all source arrays map to LLVM arrays. This
|
|
|
|
|
// will not true when we add support for VLAs.
|
|
|
|
|
llvm::Value *V = EmitLValue(E).getAddress(); // Bitfields can't be arrays.
|
|
|
|
|
|
|
|
|
|
assert(isa<llvm::PointerType>(V->getType()) &&
|
|
|
|
|
isa<llvm::ArrayType>(cast<llvm::PointerType>(V->getType())
|
|
|
|
|
->getElementType()) &&
|
|
|
|
|
"Doesn't support VLAs yet!");
|
|
|
|
|
llvm::Constant *Idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
|
|
|
|
|
V = Builder.CreateGEP(V, Idx0, Idx0, "arraydecay");
|
|
|
|
|
return ExprResult::get(V);
|
|
|
|
|
} else if (ResTy->isPromotableIntegerType()) { // C99 6.3.1.1p2
|
|
|
|
|
// FIXME: this probably isn't right, pending clarification from Steve.
|
|
|
|
|
llvm::Value *Val = EmitExpr(E).getVal();
|
|
|
|
|
|
|
|
|
|
// FIXME: this doesn't handle 'char'!.
|
|
|
|
|
|
|
|
|
|
// If the input is a signed integer, sign extend to the destination.
|
|
|
|
|
if (ResTy->isSignedIntegerType()) {
|
|
|
|
|
Val = Builder.CreateSExt(Val, LLVMIntTy, "promote");
|
|
|
|
|
} else {
|
|
|
|
|
// This handles unsigned types, including bool.
|
|
|
|
|
Val = Builder.CreateZExt(Val, LLVMIntTy, "promote");
|
|
|
|
|
}
|
|
|
|
|
ResTy = getContext().IntTy;
|
|
|
|
|
|
|
|
|
|
return ExprResult::get(Val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Otherwise, this is a float, double, int, struct, etc.
|
|
|
|
|
return EmitExpr(E);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-06-02 19:33:17 +00:00
|
|
|
ExprResult CodeGenFunction::EmitUnaryOperator(const UnaryOperator *E) {
|
|
|
|
|
switch (E->getOpcode()) {
|
|
|
|
|
default:
|
|
|
|
|
printf("Unimplemented unary expr!\n");
|
|
|
|
|
E->dump();
|
|
|
|
|
return ExprResult::get(UndefValue::get(llvm::Type::Int32Ty));
|
|
|
|
|
case UnaryOperator::LNot: return EmitUnaryLNot(E);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// C99 6.5.3.3
|
|
|
|
|
ExprResult CodeGenFunction::EmitUnaryLNot(const UnaryOperator *E) {
|
2007-06-02 22:49:07 +00:00
|
|
|
QualType ResTy;
|
|
|
|
|
ExprResult Op = EmitExprWithUsualUnaryConversions(E->getSubExpr(), ResTy);
|
2007-06-02 19:33:17 +00:00
|
|
|
|
|
|
|
|
// Compare to zero.
|
2007-06-02 22:49:07 +00:00
|
|
|
Value *BoolVal = EvaluateScalarValueToBool(Op, ResTy);
|
2007-06-02 19:33:17 +00:00
|
|
|
|
|
|
|
|
// Invert value.
|
2007-06-02 19:47:04 +00:00
|
|
|
// TODO: Could dynamically modify easy computations here. For example, if
|
|
|
|
|
// the operand is an icmp ne, turn into icmp eq.
|
2007-06-02 19:33:17 +00:00
|
|
|
BoolVal = Builder.CreateNot(BoolVal, "lnot");
|
|
|
|
|
|
|
|
|
|
// ZExt result to int.
|
2007-06-02 22:49:07 +00:00
|
|
|
const llvm::Type *ResLTy = ConvertType(E->getType(), E->getOperatorLoc());
|
|
|
|
|
return ExprResult::get(Builder.CreateZExt(BoolVal, ResLTy, "lnot.ext"));
|
2007-06-02 19:33:17 +00:00
|
|
|
}
|
|
|
|
|
|
2007-06-01 18:02:12 +00:00
|
|
|
|
2007-06-02 00:16:28 +00:00
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
|
// Binary Operator Emission
|
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
|
|
// FIXME describe.
|
|
|
|
|
void CodeGenFunction::EmitUsualArithmeticConversions(const BinaryOperator *E,
|
|
|
|
|
ExprResult &LHS,
|
|
|
|
|
ExprResult &RHS) {
|
2007-06-02 22:51:30 +00:00
|
|
|
QualType LHSType, RHSType;
|
|
|
|
|
LHS = EmitExprWithUsualUnaryConversions(E->getLHS(), LHSType);
|
|
|
|
|
RHS = EmitExprWithUsualUnaryConversions(E->getRHS(), RHSType);
|
|
|
|
|
|
2007-06-02 00:16:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ExprResult CodeGenFunction::EmitBinaryOperator(const BinaryOperator *E) {
|
|
|
|
|
switch (E->getOpcode()) {
|
|
|
|
|
default:
|
|
|
|
|
printf("Unimplemented expr!\n");
|
|
|
|
|
E->dump();
|
|
|
|
|
return ExprResult::get(UndefValue::get(llvm::Type::Int32Ty));
|
|
|
|
|
case BinaryOperator::Add: return EmitBinaryAdd(E);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ExprResult CodeGenFunction::EmitBinaryAdd(const BinaryOperator *E) {
|
|
|
|
|
ExprResult LHS, RHS;
|
|
|
|
|
|
|
|
|
|
EmitUsualArithmeticConversions(E, LHS, RHS);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ExprResult::get(Builder.CreateAdd(LHS.getVal(), RHS.getVal(), "tmp"));
|
|
|
|
|
}
|