Newer
Older
//===--- CGExpr.cpp - Emit LLVM Code from Expressions ---------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file 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 "CodeGenModule.h"
#include "clang/AST/AST.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Support/MathExtras.h"
using namespace clang;
using namespace CodeGen;
//===--------------------------------------------------------------------===//
// Miscellaneous Helper Methods
//===--------------------------------------------------------------------===//
/// CreateTempAlloca - This creates a alloca and inserts it into the entry
/// block.
llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(const llvm::Type *Ty,
const char *Name) {
return new llvm::AllocaInst(Ty, 0, Name, AllocaInsertPt);
}
/// EvaluateExprAsBool - Perform the usual unary conversions on the specified
/// expression and compare the result against zero, returning an Int1Ty value.
Chris Lattner
committed
llvm::Value *CodeGenFunction::EvaluateExprAsBool(const Expr *E) {
QualType BoolTy = getContext().BoolTy;
if (!E->getType()->isComplexType())
return EmitScalarConversion(EmitScalarExpr(E), E->getType(), BoolTy);
return EmitComplexToScalarConversion(EmitComplexExpr(E), E->getType(),BoolTy);
}
/// EmitAnyExpr - Emit code to compute the specified expression which can have
/// any type. The result is returned as an RValue struct. If this is an
/// aggregate expression, the aggloc/agglocvolatile arguments indicate where
/// the result should be returned.
RValue CodeGenFunction::EmitAnyExpr(const Expr *E, llvm::Value *AggLoc,
bool isAggLocVolatile) {
if (!hasAggregateLLVMType(E->getType()))
return RValue::get(EmitScalarExpr(E));
else if (E->getType()->isComplexType())
return RValue::getComplex(EmitComplexExpr(E));
EmitAggExpr(E, AggLoc, isAggLocVolatile);
return RValue::getAggregate(AggLoc);
}
//===----------------------------------------------------------------------===//
// LValue Expression Emission
//===----------------------------------------------------------------------===//
/// EmitLValue - Emit code to compute a designator that specifies the location
/// of the expression.
///
/// This can return one of two things: a simple address or a bitfield
/// reference. In either case, the LLVM Value* in the LValue structure is
/// guaranteed to be an LLVM pointer type.
///
/// If this returns a bitfield reference, nothing about the pointee type of
/// the LLVM value is known: For example, it may not be a pointer to an
/// integer.
///
/// If this returns a normal address, and if the lvalue's C type is fixed
/// size, this method guarantees that the returned pointer type will point to
/// an LLVM type of the same size of the lvalue's type. If the lvalue has a
/// variable length type, this is not possible.
///
LValue CodeGenFunction::EmitLValue(const Expr *E) {
switch (E->getStmtClass()) {
WarnUnsupported(E, "l-value expression");
llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(E->getType()));
return LValue::MakeAddr(llvm::UndefValue::get(Ty));
}
Christopher Lamb
committed
case Expr::CallExprClass: return EmitCallExprLValue(cast<CallExpr>(E));
case Expr::DeclRefExprClass: return EmitDeclRefLValue(cast<DeclRefExpr>(E));
case Expr::ParenExprClass:return EmitLValue(cast<ParenExpr>(E)->getSubExpr());
Anders Carlsson
committed
case Expr::PreDefinedExprClass:
return EmitPreDefinedLValue(cast<PreDefinedExpr>(E));
case Expr::StringLiteralClass:
return EmitStringLiteralLValue(cast<StringLiteral>(E));
case Expr::UnaryOperatorClass:
return EmitUnaryOpLValue(cast<UnaryOperator>(E));
case Expr::ArraySubscriptExprClass:
return EmitArraySubscriptExpr(cast<ArraySubscriptExpr>(E));
case Expr::OCUVectorElementExprClass:
return EmitOCUVectorElementExpr(cast<OCUVectorElementExpr>(E));
case Expr::MemberExprClass: return EmitMemberExpr(cast<MemberExpr>(E));
}
}
/// EmitLoadOfLValue - Given an expression that represents a value lvalue,
/// this method emits the address of the lvalue, then loads the result as an
/// rvalue, returning the rvalue.
RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) {
Chris Lattner
committed
if (LV.isSimple()) {
llvm::Value *Ptr = LV.getAddress();
const llvm::Type *EltTy =
cast<llvm::PointerType>(Ptr->getType())->getElementType();
// Simple scalar l-value.
if (EltTy->isFirstClassType()) {
llvm::Value *V = Builder.CreateLoad(Ptr, "tmp");
// Bool can have different representation in memory than in registers.
if (ExprType->isBooleanType()) {
if (V->getType() != llvm::Type::Int1Ty)
V = Builder.CreateTrunc(V, llvm::Type::Int1Ty, "tobool");
}
return RValue::get(V);
}
Chris Lattner
committed
Chris Lattner
committed
assert(ExprType->isFunctionType() && "Unknown scalar value");
return RValue::get(Ptr);
Chris Lattner
committed
}
Chris Lattner
committed
if (LV.isVectorElt()) {
llvm::Value *Vec = Builder.CreateLoad(LV.getVectorAddr(), "tmp");
return RValue::get(Builder.CreateExtractElement(Vec, LV.getVectorIdx(),
"vecext"));
}
Chris Lattner
committed
// If this is a reference to a subset of the elements of a vector, either
// shuffle the input or extract/insert them as appropriate.
if (LV.isOCUVectorElt())
return EmitLoadOfOCUElementLValue(LV, ExprType);
if (LV.isBitfield())
return EmitLoadOfBitfieldLValue(LV, ExprType);
assert(0 && "Unknown LValue type!");
//an invalid RValue, but the assert will
//ensure that this point is never reached
return RValue();
}
RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV,
QualType ExprType) {
llvm::Value *Ptr = LV.getBitfieldAddr();
const llvm::Type *EltTy =
cast<llvm::PointerType>(Ptr->getType())->getElementType();
unsigned EltTySize = EltTy->getPrimitiveSizeInBits();
unsigned short BitfieldSize = LV.getBitfieldSize();
unsigned short EndBit = LV.getBitfieldStartBit() + BitfieldSize;
llvm::Value *V = Builder.CreateLoad(Ptr, "tmp");
llvm::Value *ShAmt = llvm::ConstantInt::get(EltTy, EltTySize - EndBit);
V = Builder.CreateShl(V, ShAmt, "tmp");
ShAmt = llvm::ConstantInt::get(EltTy, EltTySize - BitfieldSize);
V = LV.isBitfieldSigned() ?
Builder.CreateAShr(V, ShAmt, "tmp") :
Builder.CreateLShr(V, ShAmt, "tmp");
return RValue::get(V);
}
// If this is a reference to a subset of the elements of a vector, either
// shuffle the input or extract/insert them as appropriate.
RValue CodeGenFunction::EmitLoadOfOCUElementLValue(LValue LV,
QualType ExprType) {
llvm::Value *Vec = Builder.CreateLoad(LV.getOCUVectorAddr(), "tmp");
unsigned EncFields = LV.getOCUVectorElts();
// If the result of the expression is a non-vector type, we must be
// extracting a single element. Just codegen as an extractelement.
const VectorType *ExprVT = ExprType->getAsVectorType();
if (!ExprVT) {
unsigned InIdx = OCUVectorElementExpr::getAccessedFieldNo(0, EncFields);
llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx);
return RValue::get(Builder.CreateExtractElement(Vec, Elt, "tmp"));
}
// If the source and destination have the same number of elements, use a
// vector shuffle instead of insert/extracts.
unsigned NumResultElts = ExprVT->getNumElements();
unsigned NumSourceElts =
cast<llvm::VectorType>(Vec->getType())->getNumElements();
if (NumResultElts == NumSourceElts) {
llvm::SmallVector<llvm::Constant*, 4> Mask;
for (unsigned i = 0; i != NumResultElts; ++i) {
unsigned InIdx = OCUVectorElementExpr::getAccessedFieldNo(i, EncFields);
Mask.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx));
Chris Lattner
committed
}
llvm::Value *MaskV = llvm::ConstantVector::get(&Mask[0], Mask.size());
Vec = Builder.CreateShuffleVector(Vec,
llvm::UndefValue::get(Vec->getType()),
MaskV, "tmp");
return RValue::get(Vec);
Chris Lattner
committed
}
// Start out with an undef of the result type.
llvm::Value *Result = llvm::UndefValue::get(ConvertType(ExprType));
// Extract/Insert each element of the result.
for (unsigned i = 0; i != NumResultElts; ++i) {
unsigned InIdx = OCUVectorElementExpr::getAccessedFieldNo(i, EncFields);
llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx);
Elt = Builder.CreateExtractElement(Vec, Elt, "tmp");
llvm::Value *OutIdx = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
Result = Builder.CreateInsertElement(Result, Elt, OutIdx, "tmp");
}
return RValue::get(Result);
}
/// EmitStoreThroughLValue - Store the specified rvalue into the specified
/// lvalue, where both are guaranteed to the have the same type, and that type
/// is 'Ty'.
void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
QualType Ty) {
if (!Dst.isSimple()) {
if (Dst.isVectorElt()) {
// Read/modify/write the vector, inserting the new element.
// FIXME: Volatility.
llvm::Value *Vec = Builder.CreateLoad(Dst.getVectorAddr(), "tmp");
Vec = Builder.CreateInsertElement(Vec, Src.getScalarVal(),
Dst.getVectorIdx(), "vecins");
Builder.CreateStore(Vec, Dst.getVectorAddr());
return;
}
// If this is an update of elements of a vector, insert them as appropriate.
if (Dst.isOCUVectorElt())
return EmitStoreThroughOCUComponentLValue(Src, Dst, Ty);
if (Dst.isBitfield())
return EmitStoreThroughBitfieldLValue(Src, Dst, Ty);
}
llvm::Value *DstAddr = Dst.getAddress();
Chris Lattner
committed
assert(Src.isScalar() && "Can't emit an agg store with this method");
// FIXME: Handle volatility etc.
const llvm::Type *SrcTy = Src.getScalarVal()->getType();
const llvm::PointerType *DstPtr = cast<llvm::PointerType>(DstAddr->getType());
const llvm::Type *AddrTy = DstPtr->getElementType();
unsigned AS = DstPtr->getAddressSpace();
Chris Lattner
committed
if (AddrTy != SrcTy)
DstAddr = Builder.CreateBitCast(DstAddr,
llvm::PointerType::get(SrcTy, AS),
Chris Lattner
committed
"storetmp");
Builder.CreateStore(Src.getScalarVal(), DstAddr);
}
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
QualType Ty) {
unsigned short StartBit = Dst.getBitfieldStartBit();
unsigned short BitfieldSize = Dst.getBitfieldSize();
llvm::Value *Ptr = Dst.getBitfieldAddr();
const llvm::Type *EltTy =
cast<llvm::PointerType>(Ptr->getType())->getElementType();
unsigned EltTySize = EltTy->getPrimitiveSizeInBits();
llvm::Value *NewVal = Src.getScalarVal();
llvm::Value *OldVal = Builder.CreateLoad(Ptr, "tmp");
llvm::Value *ShAmt = llvm::ConstantInt::get(EltTy, StartBit);
NewVal = Builder.CreateShl(NewVal, ShAmt, "tmp");
llvm::Constant *Mask = llvm::ConstantInt::get(
llvm::APInt::getBitsSet(EltTySize, StartBit,
StartBit + BitfieldSize - 1));
// Mask out any bits that shouldn't be set in the result.
NewVal = Builder.CreateAnd(NewVal, Mask, "tmp");
// Next, mask out the bits this bit-field should include from the old value.
Mask = llvm::ConstantExpr::getNot(Mask);
OldVal = Builder.CreateAnd(OldVal, Mask, "tmp");
// Finally, merge the two together and store it.
NewVal = Builder.CreateOr(OldVal, NewVal, "tmp");
Builder.CreateStore(NewVal, Ptr);
}
void CodeGenFunction::EmitStoreThroughOCUComponentLValue(RValue Src, LValue Dst,
QualType Ty) {
// This access turns into a read/modify/write of the vector. Load the input
// value now.
llvm::Value *Vec = Builder.CreateLoad(Dst.getOCUVectorAddr(), "tmp");
// FIXME: Volatility.
unsigned EncFields = Dst.getOCUVectorElts();
llvm::Value *SrcVal = Src.getScalarVal();
if (const VectorType *VTy = Ty->getAsVectorType()) {
unsigned NumSrcElts = VTy->getNumElements();
// Extract/Insert each element.
for (unsigned i = 0; i != NumSrcElts; ++i) {
llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
Elt = Builder.CreateExtractElement(SrcVal, Elt, "tmp");
unsigned Idx = OCUVectorElementExpr::getAccessedFieldNo(i, EncFields);
llvm::Value *OutIdx = llvm::ConstantInt::get(llvm::Type::Int32Ty, Idx);
Vec = Builder.CreateInsertElement(Vec, Elt, OutIdx, "tmp");
}
} else {
// If the Src is a scalar (not a vector) it must be updating one element.
unsigned InIdx = OCUVectorElementExpr::getAccessedFieldNo(0, EncFields);
llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx);
Vec = Builder.CreateInsertElement(Vec, SrcVal, Elt, "tmp");
}
Builder.CreateStore(Vec, Dst.getOCUVectorAddr());
}
LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
if (isa<BlockVarDecl>(D) || isa<ParmVarDecl>(D)) {
Chris Lattner
committed
llvm::Value *V = LocalDeclMap[D];
assert(V && "BlockVarDecl not entered in LocalDeclMap?");
Chris Lattner
committed
return LValue::MakeAddr(V);
Chris Lattner
committed
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
return LValue::MakeAddr(CGM.GetAddrOfFunctionDecl(FD, false));
} else if (const FileVarDecl *FVD = dyn_cast<FileVarDecl>(D)) {
return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(FVD, false));
}
assert(0 && "Unimp declref");
//an invalid LValue, but the assert will
//ensure that this point is never reached.
return LValue();
LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
// __extension__ doesn't affect lvalue-ness.
if (E->getOpcode() == UnaryOperator::Extension)
return EmitLValue(E->getSubExpr());
Chris Lattner
committed
switch (E->getOpcode()) {
default: assert(0 && "Unknown unary operator lvalue!");
case UnaryOperator::Deref:
return LValue::MakeAddr(EmitScalarExpr(E->getSubExpr()));
case UnaryOperator::Real:
case UnaryOperator::Imag:
LValue LV = EmitLValue(E->getSubExpr());
llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
llvm::Constant *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty,
E->getOpcode() == UnaryOperator::Imag);
llvm::Value *Ops[] = {Zero, Idx};
return LValue::MakeAddr(Builder.CreateGEP(LV.getAddress(), Ops, Ops+2,
"idx"));
}
}
LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) {
assert(!E->isWide() && "FIXME: Wide strings not supported yet!");
const char *StrData = E->getStrData();
unsigned Len = E->getByteLength();
std::string StringLiteral(StrData, StrData+Len);
return LValue::MakeAddr(CGM.GetAddrOfConstantString(StringLiteral));
Anders Carlsson
committed
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
LValue CodeGenFunction::EmitPreDefinedLValue(const PreDefinedExpr *E) {
std::string FunctionName(CurFuncDecl->getName());
std::string GlobalVarName;
switch (E->getIdentType()) {
default:
assert(0 && "unknown pre-defined ident type");
case PreDefinedExpr::Func:
GlobalVarName = "__func__.";
break;
case PreDefinedExpr::Function:
GlobalVarName = "__FUNCTION__.";
break;
case PreDefinedExpr::PrettyFunction:
// FIXME:: Demangle C++ method names
GlobalVarName = "__PRETTY_FUNCTION__.";
break;
}
GlobalVarName += CurFuncDecl->getName();
// FIXME: Can cache/reuse these within the module.
llvm::Constant *C=llvm::ConstantArray::get(FunctionName);
// Create a global variable for this.
C = new llvm::GlobalVariable(C->getType(), true,
llvm::GlobalValue::InternalLinkage,
C, GlobalVarName, CurFn->getParent());
return LValue::MakeAddr(C);
}
LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {
// The index must always be an integer, which is not an aggregate. Emit it.
Chris Lattner
committed
llvm::Value *Idx = EmitScalarExpr(E->getIdx());
Chris Lattner
committed
// If the base is a vector type, then we are forming a vector element lvalue
// with this subscript.
if (E->getLHS()->getType()->isVectorType()) {
Chris Lattner
committed
// Emit the vector as an lvalue to get its address.
LValue LHS = EmitLValue(E->getLHS());
assert(LHS.isSimple() && "Can only subscript lvalue vectors here!");
Chris Lattner
committed
// FIXME: This should properly sign/zero/extend or truncate Idx to i32.
return LValue::MakeVectorElt(LHS.getAddress(), Idx);
Chris Lattner
committed
}
// The base must be a pointer, which is not an aggregate. Emit it.
Chris Lattner
committed
llvm::Value *Base = EmitScalarExpr(E->getBase());
Chris Lattner
committed
// Extend or truncate the index type to 32 or 64-bits.
QualType IdxTy = E->getIdx()->getType();
bool IdxSigned = IdxTy->isSignedIntegerType();
Chris Lattner
committed
unsigned IdxBitwidth = cast<llvm::IntegerType>(Idx->getType())->getBitWidth();
if (IdxBitwidth != LLVMPointerWidth)
Chris Lattner
committed
Idx = Builder.CreateIntCast(Idx, llvm::IntegerType::get(LLVMPointerWidth),
IdxSigned, "idxprom");
// We know that the pointer points to a type of the correct size, unless the
// size is a VLA.
if (!E->getType()->isConstantSizeType(getContext()))
assert(0 && "VLA idx not implemented");
Chris Lattner
committed
return LValue::MakeAddr(Builder.CreateGEP(Base, Idx, "arrayidx"));
LValue CodeGenFunction::
EmitOCUVectorElementExpr(const OCUVectorElementExpr *E) {
// Emit the base vector as an l-value.
LValue Base = EmitLValue(E->getBase());
assert(Base.isSimple() && "Can only subscript lvalue vectors here!");
return LValue::MakeOCUVectorElt(Base.getAddress(),
E->getEncodedElementAccess());
LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
bool isUnion = false;
// If this is s.x, emit s as an lvalue. If it is s->x, emit s as a scalar.
if (E->isArrow()) {
BaseValue = EmitScalarExpr(BaseExpr);
const PointerType *PTy =
cast<PointerType>(BaseExpr->getType().getCanonicalType());
if (PTy->getPointeeType()->isUnionType())
isUnion = true;
}
// FIXME: this isn't right for bitfields.
if (BaseExpr->getType()->isUnionType())
isUnion = true;
FieldDecl *Field = E->getMemberDecl();
unsigned idx = CGM.getTypes().getLLVMFieldNo(Field);
llvm::Value *Idxs[2] = { llvm::Constant::getNullValue(llvm::Type::Int32Ty),
llvm::Value *V = Builder.CreateGEP(BaseValue,Idxs, Idxs + 2, "tmp");
// Match union field type.
const llvm::Type * FieldTy = ConvertType(Field->getType());
const llvm::PointerType * BaseTy =
cast<llvm::PointerType>(BaseValue->getType());
if (FieldTy != BaseTy->getElementType()) {
unsigned AS = BaseTy->getAddressSpace();
V = Builder.CreateBitCast(V,
llvm::PointerType::get(FieldTy, AS),
if (Field->isBitField()) {
CodeGenTypes::BitFieldInfo bitFieldInfo =
CGM.getTypes().getBitFieldInfo(Field);
return LValue::MakeBitfield(V, bitFieldInfo.Begin, bitFieldInfo.Size,
Field->getType()->isSignedIntegerType());
} else
return LValue::MakeAddr(V);
//===--------------------------------------------------------------------===//
// Expression Emission
//===--------------------------------------------------------------------===//
RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) {
if (const ImplicitCastExpr *IcExpr =
dyn_cast<const ImplicitCastExpr>(E->getCallee()))
if (const DeclRefExpr *DRExpr =
dyn_cast<const DeclRefExpr>(IcExpr->getSubExpr()))
if (const FunctionDecl *FDecl =
dyn_cast<const FunctionDecl>(DRExpr->getDecl()))
if (unsigned builtinID = FDecl->getIdentifier()->getBuiltinID())
return EmitBuiltinExpr(builtinID, E);
Chris Lattner
committed
llvm::Value *Callee = EmitScalarExpr(E->getCallee());
return EmitCallExpr(Callee, E->getCallee()->getType(),
E->arg_begin(), E->getNumArgs());
}
RValue CodeGenFunction::EmitCallExpr(Expr *FnExpr, Expr *const *Args,
unsigned NumArgs) {
llvm::Value *Callee = EmitScalarExpr(FnExpr);
return EmitCallExpr(Callee, FnExpr->getType(), Args, NumArgs);
Chris Lattner
committed
}
Christopher Lamb
committed
LValue CodeGenFunction::EmitCallExprLValue(const CallExpr *E) {
// Can only get l-value for call expression returning aggregate type
RValue RV = EmitCallExpr(E);
return LValue::MakeAddr(RV.getAggregateAddr());
}
RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType FnType,
Expr *const *ArgExprs, unsigned NumArgs) {
Chris Lattner
committed
// The callee type will always be a pointer to function type, get the function
// type.
FnType = cast<PointerType>(FnType.getCanonicalType())->getPointeeType();
QualType ResultType = cast<FunctionType>(FnType)->getResultType();
Chris Lattner
committed
llvm::SmallVector<llvm::Value*, 16> Args;
// Handle struct-return functions by passing a pointer to the location that
// we would like to return into.
if (hasAggregateLLVMType(ResultType)) {
// Create a temporary alloca to hold the result of the call. :(
Args.push_back(CreateTempAlloca(ConvertType(ResultType)));
// FIXME: set the stret attribute on the argument.
}
for (unsigned i = 0, e = NumArgs; i != e; ++i) {
QualType ArgTy = ArgExprs[i]->getType();
Chris Lattner
committed
if (!hasAggregateLLVMType(ArgTy)) {
// Scalar argument is passed by-value.
Args.push_back(EmitScalarExpr(ArgExprs[i]));
} else if (ArgTy->isComplexType()) {
// Make a temporary alloca to pass the argument.
llvm::Value *DestMem = CreateTempAlloca(ConvertType(ArgTy));
EmitComplexExprIntoAddr(ArgExprs[i], DestMem, false);
Args.push_back(DestMem);
} else {
llvm::Value *DestMem = CreateTempAlloca(ConvertType(ArgTy));
EmitAggExpr(ArgExprs[i], DestMem, false);
Chris Lattner
committed
}
llvm::Value *V = Builder.CreateCall(Callee, &Args[0], &Args[0]+Args.size());
if (V->getType() != llvm::Type::VoidTy)
V->setName("call");
else if (ResultType->isComplexType())
return RValue::getComplex(LoadComplexFromAddr(Args[0], false));
else if (hasAggregateLLVMType(ResultType))
// Struct return.
return RValue::getAggregate(Args[0]);
else {
// void return.
assert(ResultType->isVoidType() && "Should only have a void expr here");
return RValue::get(V);
}