summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGExpr.cpp')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp615
1 files changed, 615 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
new file mode 100644
index 00000000000..932a5c5da8b
--- /dev/null
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -0,0 +1,615 @@
+//===--- 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.
+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()) {
+ default: {
+ WarnUnsupported(E, "l-value expression");
+ llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(E->getType()));
+ return LValue::MakeAddr(llvm::UndefValue::get(Ty));
+ }
+
+ 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());
+ 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) {
+ 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);
+ }
+
+ assert(ExprType->isFunctionType() && "Unknown scalar value");
+ return RValue::get(Ptr);
+ }
+
+ if (LV.isVectorElt()) {
+ llvm::Value *Vec = Builder.CreateLoad(LV.getVectorAddr(), "tmp");
+ return RValue::get(Builder.CreateExtractElement(Vec, LV.getVectorIdx(),
+ "vecext"));
+ }
+
+ // 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));
+ }
+
+ 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);
+ }
+
+ // 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);
+
+ assert(0 && "Unknown LValue type");
+ }
+
+ llvm::Value *DstAddr = Dst.getAddress();
+ 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();
+
+ if (AddrTy != SrcTy)
+ DstAddr = Builder.CreateBitCast(DstAddr,
+ llvm::PointerType::get(SrcTy, AS),
+ "storetmp");
+ Builder.CreateStore(Src.getScalarVal(), DstAddr);
+}
+
+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));
+
+ // 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) {
+ const ValueDecl *D = E->getDecl();
+ if (isa<BlockVarDecl>(D) || isa<ParmVarDecl>(D)) {
+ const VarDecl *VD = cast<VarDecl>(D);
+ if (VD->getStorageClass() == VarDecl::Extern)
+ return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD, false));
+ else {
+ llvm::Value *V = LocalDeclMap[D];
+ assert(V && "BlockVarDecl not entered in LocalDeclMap?");
+ return LValue::MakeAddr(V);
+ }
+ } 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());
+
+ 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));
+}
+
+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.
+ llvm::Value *Idx = EmitScalarExpr(E->getIdx());
+
+ // If the base is a vector type, then we are forming a vector element lvalue
+ // with this subscript.
+ if (E->getLHS()->getType()->isVectorType()) {
+ // Emit the vector as an lvalue to get its address.
+ LValue LHS = EmitLValue(E->getLHS());
+ assert(LHS.isSimple() && "Can only subscript lvalue vectors here!");
+ // FIXME: This should properly sign/zero/extend or truncate Idx to i32.
+ return LValue::MakeVectorElt(LHS.getAddress(), Idx);
+ }
+
+ // The base must be a pointer, which is not an aggregate. Emit it.
+ llvm::Value *Base = EmitScalarExpr(E->getBase());
+
+ // Extend or truncate the index type to 32 or 64-bits.
+ QualType IdxTy = E->getIdx()->getType();
+ bool IdxSigned = IdxTy->isSignedIntegerType();
+ unsigned IdxBitwidth = cast<llvm::IntegerType>(Idx->getType())->getBitWidth();
+ if (IdxBitwidth != LLVMPointerWidth)
+ 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())
+ assert(0 && "VLA idx not implemented");
+ 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;
+ Expr *BaseExpr = E->getBase();
+ llvm::Value *BaseValue = NULL;
+
+ // 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;
+ }
+ else {
+ LValue BaseLV = EmitLValue(BaseExpr);
+ // FIXME: this isn't right for bitfields.
+ BaseValue = BaseLV.getAddress();
+ if (BaseExpr->getType()->isUnionType())
+ isUnion = true;
+ }
+
+ FieldDecl *Field = E->getMemberDecl();
+ return EmitLValueForField(BaseValue, Field, isUnion);
+}
+
+LValue CodeGenFunction::EmitLValueForField(llvm::Value* BaseValue,
+ FieldDecl* Field,
+ bool isUnion)
+{
+ llvm::Value *V;
+ unsigned idx = CGM.getTypes().getLLVMFieldNo(Field);
+
+ if (Field->isBitField()) {
+ const llvm::Type * FieldTy = ConvertType(Field->getType());
+ const llvm::PointerType * BaseTy =
+ cast<llvm::PointerType>(BaseValue->getType());
+ unsigned AS = BaseTy->getAddressSpace();
+ BaseValue = Builder.CreateBitCast(BaseValue,
+ llvm::PointerType::get(FieldTy, AS),
+ "tmp");
+ V = Builder.CreateGEP(BaseValue,
+ llvm::ConstantInt::get(llvm::Type::Int32Ty, idx),
+ "tmp");
+ } else {
+ llvm::Value *Idxs[2] = { llvm::Constant::getNullValue(llvm::Type::Int32Ty),
+ llvm::ConstantInt::get(llvm::Type::Int32Ty, idx) };
+ V = Builder.CreateGEP(BaseValue,Idxs, Idxs + 2, "tmp");
+ }
+ // Match union field type.
+ if (isUnion) {
+ 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),
+ "tmp");
+ }
+ }
+
+ 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);
+
+ 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);
+}
+
+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) {
+ // 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();
+
+ 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();
+
+ 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);
+ Args.push_back(DestMem);
+ }
+ }
+
+ llvm::CallInst *CI = Builder.CreateCall(Callee,&Args[0],&Args[0]+Args.size());
+ if (const llvm::Function *F = dyn_cast<llvm::Function>(Callee))
+ CI->setCallingConv(F->getCallingConv());
+ if (CI->getType() != llvm::Type::VoidTy)
+ CI->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");
+ CI = 0;
+ }
+
+ return RValue::get(CI);
+}
OpenPOWER on IntegriCloud