aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExpr.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2012-08-15 20:02:54 +0000
committerDimitry Andric <dim@FreeBSD.org>2012-08-15 20:02:54 +0000
commit56d91b49b13fe55c918afbda19f6165b5fbff87a (patch)
tree9abb1a658a297776086f4e0dfa6ca533de02104e /lib/CodeGen/CGExpr.cpp
parent41e20f564abdb05101d6b2b29c59459a966c22cc (diff)
downloadsrc-56d91b49b13fe55c918afbda19f6165b5fbff87a.tar.gz
src-56d91b49b13fe55c918afbda19f6165b5fbff87a.zip
Vendor import of clang trunk r161861:vendor/clang/clang-trunk-r161861
Notes
Notes: svn path=/vendor/clang/dist/; revision=239313 svn path=/vendor/clang/clang-trunk-r161861/; revision=239314; tag=vendor/clang/clang-trunk-r161861
Diffstat (limited to 'lib/CodeGen/CGExpr.cpp')
-rw-r--r--lib/CodeGen/CGExpr.cpp239
1 files changed, 143 insertions, 96 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 5f2b1f055dba..ecee7b4931be 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -21,10 +21,11 @@
#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/Basic/ConvertUTF.h"
#include "clang/Frontend/CodeGenOptions.h"
#include "llvm/Intrinsics.h"
#include "llvm/LLVMContext.h"
-#include "llvm/Support/MDBuilder.h"
+#include "llvm/MDBuilder.h"
#include "llvm/Target/TargetData.h"
using namespace clang;
using namespace CodeGen;
@@ -108,15 +109,18 @@ void CodeGenFunction::EmitIgnoredExpr(const Expr *E) {
/// can have any type. The result is returned as an RValue struct.
/// If this is an aggregate expression, AggSlot indicates where the
/// result should be returned.
-RValue CodeGenFunction::EmitAnyExpr(const Expr *E, AggValueSlot AggSlot,
- bool IgnoreResult) {
+RValue CodeGenFunction::EmitAnyExpr(const Expr *E,
+ AggValueSlot aggSlot,
+ bool ignoreResult) {
if (!hasAggregateLLVMType(E->getType()))
- return RValue::get(EmitScalarExpr(E, IgnoreResult));
+ return RValue::get(EmitScalarExpr(E, ignoreResult));
else if (E->getType()->isAnyComplexType())
- return RValue::getComplex(EmitComplexExpr(E, IgnoreResult, IgnoreResult));
+ return RValue::getComplex(EmitComplexExpr(E, ignoreResult, ignoreResult));
- EmitAggExpr(E, AggSlot, IgnoreResult);
- return AggSlot.asRValue();
+ if (!ignoreResult && aggSlot.isIgnored())
+ aggSlot = CreateAggTemp(E->getType(), "agg-temp");
+ EmitAggExpr(E, aggSlot);
+ return aggSlot.asRValue();
}
/// EmitAnyExprToTemp - Similary to EmitAnyExpr(), however, the result will
@@ -156,7 +160,11 @@ namespace {
/// \brief An adjustment to be made to the temporary created when emitting a
/// reference binding, which accesses a particular subobject of that temporary.
struct SubobjectAdjustment {
- enum { DerivedToBaseAdjustment, FieldAdjustment } Kind;
+ enum {
+ DerivedToBaseAdjustment,
+ FieldAdjustment,
+ MemberPointerAdjustment
+ } Kind;
union {
struct {
@@ -165,6 +173,11 @@ namespace {
} DerivedToBase;
FieldDecl *Field;
+
+ struct {
+ const MemberPointerType *MPT;
+ llvm::Value *Ptr;
+ } Ptr;
};
SubobjectAdjustment(const CastExpr *BasePath,
@@ -178,6 +191,12 @@ namespace {
: Kind(FieldAdjustment) {
this->Field = Field;
}
+
+ SubobjectAdjustment(const MemberPointerType *MPT, llvm::Value *Ptr)
+ : Kind(MemberPointerAdjustment) {
+ this->Ptr.MPT = MPT;
+ this->Ptr.Ptr = Ptr;
+ }
};
}
@@ -345,6 +364,15 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
continue;
}
}
+ } else if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
+ if (BO->isPtrMemOp()) {
+ assert(BO->getLHS()->isRValue());
+ E = BO->getLHS();
+ const MemberPointerType *MPT =
+ BO->getRHS()->getType()->getAs<MemberPointerType>();
+ llvm::Value *Ptr = CGF.EmitScalarExpr(BO->getRHS());
+ Adjustments.push_back(SubobjectAdjustment(MPT, Ptr));
+ }
}
if (const OpaqueValueExpr *opaque = dyn_cast<OpaqueValueExpr>(E))
@@ -417,6 +445,11 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
break;
}
+ case SubobjectAdjustment::MemberPointerAdjustment: {
+ Object = CGF.CGM.getCXXABI().EmitMemberDataPointerAddress(
+ CGF, Object, Adjustment.Ptr.Ptr, Adjustment.Ptr.MPT);
+ break;
+ }
}
}
@@ -462,7 +495,7 @@ CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E,
if (ReferenceTemporaryDtor) {
llvm::Constant *DtorFn =
CGM.GetAddrOfCXXDestructor(ReferenceTemporaryDtor, Dtor_Complete);
- EmitCXXGlobalDtorRegistration(DtorFn,
+ CGM.getCXXABI().registerGlobalDtor(*this, DtorFn,
cast<llvm::Constant>(ReferenceTemporary));
} else {
assert(!ObjCARCReferenceLifetimeType.isNull());
@@ -525,15 +558,9 @@ void CodeGenFunction::EmitCheck(llvm::Value *Address, unsigned Size) {
llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, IntPtrTy);
- // In time, people may want to control this and use a 1 here.
- llvm::Value *Arg = Builder.getFalse();
- llvm::Value *C = Builder.CreateCall2(F, Address, Arg);
+ llvm::Value *Min = Builder.getFalse();
+ llvm::Value *C = Builder.CreateCall2(F, Address, Min);
llvm::BasicBlock *Cont = createBasicBlock();
- llvm::BasicBlock *Check = createBasicBlock();
- llvm::Value *NegativeOne = llvm::ConstantInt::get(IntPtrTy, -1ULL);
- Builder.CreateCondBr(Builder.CreateICmpEQ(C, NegativeOne), Cont, Check);
-
- EmitBlock(Check);
Builder.CreateCondBr(Builder.CreateICmpUGE(C,
llvm::ConstantInt::get(IntPtrTy, Size)),
Cont, getTrapBB());
@@ -676,10 +703,7 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
case Expr::PseudoObjectExprClass:
return EmitPseudoObjectLValue(cast<PseudoObjectExpr>(E));
case Expr::InitListExprClass:
- assert(cast<InitListExpr>(E)->getNumInits() == 1 &&
- "Only single-element init list can be lvalue.");
- return EmitLValue(cast<InitListExpr>(E)->getInit(0));
-
+ return EmitInitListLValue(cast<InitListExpr>(E));
case Expr::CXXTemporaryObjectExprClass:
case Expr::CXXConstructExprClass:
return EmitCXXConstructLValue(cast<CXXConstructExpr>(E));
@@ -880,7 +904,6 @@ llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) {
CGM.getCodeGenOpts().StrictEnums &&
!ET->getDecl()->isFixed());
bool IsBool = hasBooleanRepresentation(Ty);
- llvm::Type *LTy;
if (!IsBool && !IsRegularCPlusPlusEnum)
return NULL;
@@ -889,10 +912,9 @@ llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) {
if (IsBool) {
Min = llvm::APInt(8, 0);
End = llvm::APInt(8, 2);
- LTy = Int8Ty;
} else {
const EnumDecl *ED = ET->getDecl();
- LTy = ConvertTypeForMem(ED->getIntegerType());
+ llvm::Type *LTy = ConvertTypeForMem(ED->getIntegerType());
unsigned Bitwidth = LTy->getScalarSizeInBits();
unsigned NumNegativeBits = ED->getNumNegativeBits();
unsigned NumPositiveBits = ED->getNumPositiveBits();
@@ -1028,6 +1050,9 @@ RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV) {
llvm::Value *Res = 0;
for (unsigned i = 0, e = Info.getNumComponents(); i != e; ++i) {
const CGBitFieldInfo::AccessInfo &AI = Info.getComponent(i);
+ CharUnits AccessAlignment = AI.AccessAlignment;
+ if (!LV.getAlignment().isZero())
+ AccessAlignment = std::min(AccessAlignment, LV.getAlignment());
// Get the field pointer.
llvm::Value *Ptr = LV.getBitFieldBaseAddr();
@@ -1051,8 +1076,7 @@ RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV) {
// Perform the load.
llvm::LoadInst *Load = Builder.CreateLoad(Ptr, LV.isVolatileQualified());
- if (!AI.AccessAlignment.isZero())
- Load->setAlignment(AI.AccessAlignment.getQuantity());
+ Load->setAlignment(AccessAlignment.getQuantity());
// Shift out unused low bits and mask out unused high bits.
llvm::Value *Val = Load;
@@ -1251,6 +1275,9 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
// Iterate over the components, writing each piece to memory.
for (unsigned i = 0, e = Info.getNumComponents(); i != e; ++i) {
const CGBitFieldInfo::AccessInfo &AI = Info.getComponent(i);
+ CharUnits AccessAlignment = AI.AccessAlignment;
+ if (!Dst.getAlignment().isZero())
+ AccessAlignment = std::min(AccessAlignment, Dst.getAlignment());
// Get the field pointer.
llvm::Value *Ptr = Dst.getBitFieldBaseAddr();
@@ -1297,8 +1324,7 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
// If necessary, load and OR in bits that are outside of the bit-field.
if (AI.TargetBitWidth != AI.AccessWidth) {
llvm::LoadInst *Load = Builder.CreateLoad(Ptr, Dst.isVolatileQualified());
- if (!AI.AccessAlignment.isZero())
- Load->setAlignment(AI.AccessAlignment.getQuantity());
+ Load->setAlignment(AccessAlignment.getQuantity());
// Compute the mask for zeroing the bits that are part of the bit-field.
llvm::APInt InvMask =
@@ -1312,8 +1338,7 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
// Write the value.
llvm::StoreInst *Store = Builder.CreateStore(Val, Ptr,
Dst.isVolatileQualified());
- if (!AI.AccessAlignment.isZero())
- Store->setAlignment(AI.AccessAlignment.getQuantity());
+ Store->setAlignment(AccessAlignment.getQuantity());
}
}
@@ -1683,6 +1708,39 @@ LValue CodeGenFunction::EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E) {
E->getType());
}
+static llvm::Constant*
+GetAddrOfConstantWideString(StringRef Str,
+ const char *GlobalName,
+ ASTContext &Context,
+ QualType Ty, SourceLocation Loc,
+ CodeGenModule &CGM) {
+
+ StringLiteral *SL = StringLiteral::Create(Context,
+ Str,
+ StringLiteral::Wide,
+ /*Pascal = */false,
+ Ty, Loc);
+ llvm::Constant *C = CGM.GetConstantArrayFromStringLiteral(SL);
+ llvm::GlobalVariable *GV =
+ new llvm::GlobalVariable(CGM.getModule(), C->getType(),
+ !CGM.getLangOpts().WritableStrings,
+ llvm::GlobalValue::PrivateLinkage,
+ C, GlobalName);
+ const unsigned WideAlignment =
+ Context.getTypeAlignInChars(Ty).getQuantity();
+ GV->setAlignment(WideAlignment);
+ return GV;
+}
+
+static void ConvertUTF8ToWideString(unsigned CharByteWidth, StringRef Source,
+ SmallString<32>& Target) {
+ Target.resize(CharByteWidth * (Source.size() + 1));
+ char* ResultPtr = &Target[0];
+ bool success = ConvertUTF8toWide(CharByteWidth, Source, ResultPtr);
+ (void)success;
+ assert(success);
+ Target.resize(ResultPtr - &Target[0]);
+}
LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
switch (E->getIdentType()) {
@@ -1691,11 +1749,12 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
case PredefinedExpr::Func:
case PredefinedExpr::Function:
+ case PredefinedExpr::LFunction:
case PredefinedExpr::PrettyFunction: {
- unsigned Type = E->getIdentType();
+ unsigned IdentType = E->getIdentType();
std::string GlobalVarName;
- switch (Type) {
+ switch (IdentType) {
default: llvm_unreachable("Invalid type");
case PredefinedExpr::Func:
GlobalVarName = "__func__.";
@@ -1703,6 +1762,9 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
case PredefinedExpr::Function:
GlobalVarName = "__FUNCTION__.";
break;
+ case PredefinedExpr::LFunction:
+ GlobalVarName = "L__FUNCTION__.";
+ break;
case PredefinedExpr::PrettyFunction:
GlobalVarName = "__PRETTY_FUNCTION__.";
break;
@@ -1720,10 +1782,27 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
std::string FunctionName =
(isa<BlockDecl>(CurDecl)
? FnName.str()
- : PredefinedExpr::ComputeName((PredefinedExpr::IdentType)Type, CurDecl));
-
- llvm::Constant *C =
- CGM.GetAddrOfConstantCString(FunctionName, GlobalVarName.c_str());
+ : PredefinedExpr::ComputeName((PredefinedExpr::IdentType)IdentType,
+ CurDecl));
+
+ const Type* ElemType = E->getType()->getArrayElementTypeNoTypeQual();
+ llvm::Constant *C;
+ if (ElemType->isWideCharType()) {
+ SmallString<32> RawChars;
+ ConvertUTF8ToWideString(
+ getContext().getTypeSizeInChars(ElemType).getQuantity(),
+ FunctionName, RawChars);
+ C = GetAddrOfConstantWideString(RawChars,
+ GlobalVarName.c_str(),
+ getContext(),
+ E->getType(),
+ E->getLocation(),
+ CGM);
+ } else {
+ C = CGM.GetAddrOfConstantCString(FunctionName,
+ GlobalVarName.c_str(),
+ 1);
+ }
return MakeAddrLValue(C, E->getType());
}
}
@@ -1794,25 +1873,6 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {
// Extend or truncate the index type to 32 or 64-bits.
if (Idx->getType() != IntPtrTy)
Idx = Builder.CreateIntCast(Idx, IntPtrTy, IdxSigned, "idxprom");
-
- // FIXME: As llvm implements the object size checking, this can come out.
- if (CatchUndefined) {
- if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E->getBase())){
- if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr())) {
- if (ICE->getCastKind() == CK_ArrayToPointerDecay) {
- if (const ConstantArrayType *CAT
- = getContext().getAsConstantArrayType(DRE->getType())) {
- llvm::APInt Size = CAT->getSize();
- llvm::BasicBlock *Cont = createBasicBlock("cont");
- Builder.CreateCondBr(Builder.CreateICmpULE(Idx,
- llvm::ConstantInt::get(Idx->getType(), Size)),
- Cont, getTrapBB());
- EmitBlock(Cont);
- }
- }
- }
- }
- }
// We know that the pointer points to a type of the correct size, unless the
// size is a VLA or Objective-C interface.
@@ -1996,43 +2056,17 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
llvm_unreachable("Unhandled member declaration!");
}
-LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value *BaseValue,
- const FieldDecl *Field,
- unsigned CVRQualifiers) {
- const CGRecordLayout &RL =
- CGM.getTypes().getCGRecordLayout(Field->getParent());
- const CGBitFieldInfo &Info = RL.getBitFieldInfo(Field);
- return LValue::MakeBitfield(BaseValue, Info,
- Field->getType().withCVRQualifiers(CVRQualifiers));
-}
-
-/// EmitLValueForAnonRecordField - Given that the field is a member of
-/// an anonymous struct or union buried inside a record, and given
-/// that the base value is a pointer to the enclosing record, derive
-/// an lvalue for the ultimate field.
-LValue CodeGenFunction::EmitLValueForAnonRecordField(llvm::Value *BaseValue,
- const IndirectFieldDecl *Field,
- unsigned CVRQualifiers) {
- IndirectFieldDecl::chain_iterator I = Field->chain_begin(),
- IEnd = Field->chain_end();
- while (true) {
- QualType RecordTy =
- getContext().getTypeDeclType(cast<FieldDecl>(*I)->getParent());
- LValue LV = EmitLValueForField(MakeAddrLValue(BaseValue, RecordTy),
- cast<FieldDecl>(*I));
- if (++I == IEnd) return LV;
-
- assert(LV.isSimple());
- BaseValue = LV.getAddress();
- CVRQualifiers |= LV.getVRQualifiers();
- }
-}
-
LValue CodeGenFunction::EmitLValueForField(LValue base,
const FieldDecl *field) {
- if (field->isBitField())
- return EmitLValueForBitfield(base.getAddress(), field,
- base.getVRQualifiers());
+ if (field->isBitField()) {
+ const CGRecordLayout &RL =
+ CGM.getTypes().getCGRecordLayout(field->getParent());
+ const CGBitFieldInfo &Info = RL.getBitFieldInfo(field);
+ QualType fieldType =
+ field->getType().withCVRQualifiers(base.getVRQualifiers());
+ return LValue::MakeBitfield(base.getAddress(), Info, fieldType,
+ base.getAlignment());
+ }
const RecordDecl *rec = field->getParent();
QualType type = field->getType();
@@ -2144,7 +2178,10 @@ LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){
llvm::Value *GlobalPtr = CGM.GetAddrOfConstantCompoundLiteral(E);
return MakeAddrLValue(GlobalPtr, E->getType());
}
-
+ if (E->getType()->isVariablyModifiedType())
+ // make sure to emit the VLA size.
+ EmitVariablyModifiedType(E->getType());
+
llvm::Value *DeclPtr = CreateMemTemp(E->getType(), ".compoundliteral");
const Expr *InitExpr = E->getInitializer();
LValue Result = MakeAddrLValue(DeclPtr, E->getType());
@@ -2155,6 +2192,16 @@ LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){
return Result;
}
+LValue CodeGenFunction::EmitInitListLValue(const InitListExpr *E) {
+ if (!E->isGLValue())
+ // Initializing an aggregate temporary in C++11: T{...}.
+ return EmitAggExprToLValue(E);
+
+ // An lvalue initializer list must be initializing a reference.
+ assert(E->getNumInits() == 1 && "reference init with multiple values");
+ return EmitLValue(E->getInit(0));
+}
+
LValue CodeGenFunction::
EmitConditionalOperatorLValue(const AbstractConditionalOperator *expr) {
if (!expr->isGLValue()) {
@@ -2214,11 +2261,11 @@ EmitConditionalOperatorLValue(const AbstractConditionalOperator *expr) {
return MakeAddrLValue(phi, expr->getType());
}
-/// EmitCastLValue - Casts are never lvalues unless that cast is a dynamic_cast.
-/// If the cast is a dynamic_cast, we can have the usual lvalue result,
+/// EmitCastLValue - Casts are never lvalues unless that cast is to a reference
+/// type. If the cast is to a reference, we can have the usual lvalue result,
/// otherwise if a cast is needed by the code generator in an lvalue context,
/// then it must mean that we need the address of an aggregate in order to
-/// access one of its fields. This can happen for all the reasons that casts
+/// access one of its members. This can happen for all the reasons that casts
/// are permitted with aggregate result, including noop aggregate casts, and
/// cast from scalar to union.
LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
@@ -2648,7 +2695,7 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,
EmitCallArgs(Args, dyn_cast<FunctionProtoType>(FnType), ArgBeg, ArgEnd);
const CGFunctionInfo &FnInfo =
- CGM.getTypes().arrangeFunctionCall(Args, FnType);
+ CGM.getTypes().arrangeFreeFunctionCall(Args, FnType);
// C99 6.5.2.2p6:
// If the expression that denotes the called function has a type
@@ -3038,7 +3085,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {
getContext().IntTy);
const CGFunctionInfo &FuncInfo =
- CGM.getTypes().arrangeFunctionCall(RetTy, Args,
+ CGM.getTypes().arrangeFreeFunctionCall(RetTy, Args,
FunctionType::ExtInfo(), RequiredArgs::All);
llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo);
llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName);